poj 2356 Find a multiple(鸽巢原理)
2016-05-20 21:46
197 查看
题意:给出一个数N,接着再给出N个数,要你从这N个数中任意选择1个或多个数,使得其和是N的倍数。
如果找不到这样的答案 则输出0。
答案可能有多个,但智勇任意输出一个解就行。
输出的第一行是选择元素的个数M,接着M行分别是选择的元素的值
思路:刚开始的时候并不同为什么这一题回事抽屉原理,分析后才有体会,实际上此题一定有解,不存在输出0的结果。
证明如下:
我们可以依次求出N个数中部分数字组合的情况(实际上组合的数目比下列这些多):a[0],a[0]+a[1],a[0]+a[1]+a[2],......,a[0]+a[1]+a[2]...+a
;
假设分别是sum[0],sum[1],sum[2],......,sum
如果在某一项存在是N的倍数即sum[i]%N=0,可直接从第一项开始直接输出答案。
但如果不存在,则sum[i]%N的值必定在[1,N-1]之间,又由于有n项sum,有鸽巢(抽屉)原理:
这里sum[i]%N的余数为巢,即N个巢,数字组合的数目为鸽子,即鸽子数目大于N个。
则必定有一对i,j,使得sum[i]=sum[j],其中i!=j,不妨设j>i
则(sum[j]-sum[i])%N=0,故sum[j]-sum[i]是N的倍数。
则只要输出从i+1~j的所有的a的值就是答案。
然后就利用这个思路就可以直接的解出该题的答案。
如果找不到这样的答案 则输出0。
答案可能有多个,但智勇任意输出一个解就行。
输出的第一行是选择元素的个数M,接着M行分别是选择的元素的值
思路:刚开始的时候并不同为什么这一题回事抽屉原理,分析后才有体会,实际上此题一定有解,不存在输出0的结果。
证明如下:
我们可以依次求出N个数中部分数字组合的情况(实际上组合的数目比下列这些多):a[0],a[0]+a[1],a[0]+a[1]+a[2],......,a[0]+a[1]+a[2]...+a
;
假设分别是sum[0],sum[1],sum[2],......,sum
如果在某一项存在是N的倍数即sum[i]%N=0,可直接从第一项开始直接输出答案。
但如果不存在,则sum[i]%N的值必定在[1,N-1]之间,又由于有n项sum,有鸽巢(抽屉)原理:
把多于n个的物体放到n个抽屉里,则至少有一个抽屉里有2个或2个以上的物体。
这里sum[i]%N的余数为巢,即N个巢,数字组合的数目为鸽子,即鸽子数目大于N个。
则必定有一对i,j,使得sum[i]=sum[j],其中i!=j,不妨设j>i
则(sum[j]-sum[i])%N=0,故sum[j]-sum[i]是N的倍数。
则只要输出从i+1~j的所有的a的值就是答案。
然后就利用这个思路就可以直接的解出该题的答案。
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int a[10000] ; int mod[10000] ;//mod存储判断sum%n是否出现过,如果没出现时-1,如果出现,则是此时sum对应的k值,即前k项和 int sum [10001];//sum存储的与描述略有不同,sum[k]=a[0]+a[1]+...+a[k-1]; int main() { int n ; int i ; while ( cin >> n ) { memset ( mod , -1 , sizeof ( mod ) ) ; sum[0]=0; for ( i = 0 ; i < n ; i ++ ) { cin >> a[i] ; } for ( i = 0 ; i < n ; i ++ ) { sum[i+1]=sum[i]+a[i]; if ( sum [i+1] % n == 0 ) { //如果是N的倍数,则输出 int j ; cout<<i+1<<endl; for ( j = 0 ; j <= i ; j ++ ) cout<<a[j]<<endl; break; } if ( mod[sum [i+1] % n]!=-1) { //如果找到两个数的余数相同,则依次输出 int j ; cout<<i-mod[sum [i+1] % n]<<endl; for ( j = mod[sum [i+1] % n]+1 ; j <= i ; j ++ ) cout<<a[j]<<endl; break; } mod[sum [i+1] % n]=i;//将此时对应的余数存到mod中,值为此时的i } } return 0; }
相关文章推荐
- HDU3727 Jewel(主席树)
- 习题 8-18 UVA - 1619 Feel Good 感觉不错 (容斥定理)
- 漂亮的servlet-2,后台记录
- ubuntu16.04为firefox添加pepperflash插件
- ThinkPHP表单操作(未加验证)
- sql盲注及其相关方法
- 构建高性能 ASP.NET应用的12点建
- 芯片新知识
- Java 设计模式 -- 职责链模式
- tomcat 设置CATALINA_PID, shutdown失败后,会kill pid
- Android之Bundle类
- TCP/IP中MSL详解
- 哈理工OJ 1029 Function Run Fun(记忆思想)
- clazz.isArray()
- win10下sourcetree使用密钥克隆仓库时提示一直在加载的解决办法
- python
- 为什么要设置Java环境变量(详解)
- poj 1061 青蛙的约会 (扩展欧几里得模板)
- NYOJ 954 N! (数学)
- 判断一个链表是否为回文结构