本文主要是介绍抽屉原理入门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
E - 鸽巢原理入门1
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status
Description
Every year there is the same problem at Halloween: Each neighbour is only willing to give a certain total number of sweets on that day, no matter how many children call on him, so it may happen that a child will get nothing if it is too late. To avoid conflicts, the children have decided they will put all sweets together and then divide them evenly among themselves. From last year's experience of Halloween they know how many sweets they get from each neighbour. Since they care more about justice than about the number of sweets they get, they want to select a subset of the neighbours to visit, so that in sharing every child receives the same number of sweets. They will not be satisfied if they have any sweets left which cannot be divided.
Your job is to help the children and present a solution.
Output
For each test case output one line with the indices of the neighbours the children should select (here, index i corresponds to neighbour i who gives a total number of ai sweets). If there is no solution where each child gets at least one sweet print "no sweets" instead. Note that if there are several solutions where each child gets at least one sweet, you may print any of them.
Sample Output
3 5
2 3 4
————int64.。。。
抽屉定理:s[i] = a[1]+...+a[i],c[i] = s[i]%n;
因为c[i]最多有n种可能,我们不考虑c[i]==0的情况,所以有N-1种情况,所以根据抽屉原理,这n个数至少有一个c[i]彼此等于,即c[j] - c[i] ==0,即s[j]%n - s[i]%n ==0----->(s[j]-s[i])%n==0------->i+1到j是满足条件的。
简单一句话,c[0]出现一次即可,c[n!=0]出现两次即可。
#include<stdio.h>
#include<string.h>
int a[100010],b[100010],c[100010];
__int64 s[100010];
int main(){int n,m;while(scanf("%d%d",&n,&m),n||m){memset(c,-1,sizeof(c));s[0] = 0;for(int i=1;i<=m;i++){scanf("%d",&a[i]);s[i] = s[i-1]+a[i];}c[0] = 0;for(int i=1;i<=m;i++){int j;if(c[s[i]%n]!=-1){for(j=c[s[i]%n]+1;j<i;j++)printf("%d ",j);printf("%d\n",i);break;}c[s[i]%n] = i;}
}
}
这篇关于抽屉原理入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!