首页 > 代码库 > poj 3370 Halloween treats
poj 3370 Halloween treats
这题用抽屉原理写起来真的很简单,从中也明白数学的重要性。
几个抽屉原理如下:
原理1 把多于n个的物体放到n个抽屉里,则至少有一个抽屉里的东西不少于两件;
原理2 把多于mn(m乘以n)个的物体放到n个抽屉里,则至少有一个抽屉里有不少于m+1的物体。
原理3 把无穷多件物体放入n个抽屉,则至少有一个抽屉里 有无穷个物体。.
原理 4 把(mn-1)个物体放入n个抽屉中,其中必有一个抽屉中至多有(m—1)个物体。
这题的题意很简单,就是求出哪些数加起来能够被某个数整除。我们知道一个整数n有n个同余类,这n个同余类就可以看做n个抽屉,而题目中给出c<=n,再加上0,那么就有n+1个数,大于c,由原理1可以知道一定存在这样的整数,满足题意。因为至少有两个数的余数相同,那么两者相减之后一定能被c整除。
因此我们可以用一个mod[i]数组来记录从0到i所有整数的和%c的值,这样,当mod[i]=0或者mod[i]=a之前出现过,那么就可以得出,从之前出现的那个数开始的下一个数到i为止的数加起来一定能被c整除,例如:如果mod[2]=1,并且mod[5]=1,那么从3到5这三个数加起来一定能够被c整除。
#include<cstdio> #include<cstring> const int N=100005; int sweet[N],mod[N]; bool isok[N]; int main() { int c,n; while(scanf("%d%d",&c,&n)) { if(c==0&&n==0) break; memset(isok,false,sizeof(isok)); sweet[0]=0,mod[0]=0; long long sum=0;//这里要注意,不能用int。 for(int i=1;i<=n;i++) { scanf("%d",&sweet[i]); sum+=sweet[i]; mod[i]=sum%c; } int start=0; for(int i=n;i>=0;i--) { if(isok[mod[i]]) { start=i; break; } isok[mod[i]]=true; } //printf("start=%d\n",start); int e=start+1; while(true) { printf("%d ",e); e++; if(mod[start]==mod[e]) break; } printf("%d\n",e); } return 0; }
poj 3370 Halloween treats
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。