poj2356 Find a multiple(抽屉原理|鸽巢原理)

时间:2023-05-29 23:18:56
/*
引用过来的
题意:
给出N个数,问其中是否存在M个数使其满足M个数的和是N的倍数,如果有多组解,
随意输出一组即可。若不存在,输出 0。
题解:
首先必须声明的一点是本题是一定是有解的。原理根据抽屉原理:
因为有n个数,对n个数取余,如果余数中没有出现0,根据鸽巢原理,一定有两个数的余数相同,
如果余数出现0,自然就是n的倍数。也就是说,n个数中一定存在一些数的和是n的倍数。
本题的思路是从第一个数开始一次求得前 i(i <= N)项的和关于N的余数sum,并依次记录相应余数的存在状态,
如果sum == 0;则从第一项到第i项的和即满足题意。如果求得的 sum 在前边已经出现过,假设在第j(j<i)项出现
过相同的 sum 值,则从第 j+1 项到第i项的和一定满足题意。
*/
#include<stdio.h>
#include<string.h>
#define MAX 16000
int s[MAX],sum[MAX],has[MAX];
int main(void)
{
int n,i,j;
while(scanf("%d",&n)!=EOF)
{
int l,r;
memset(has,-,sizeof(has));
memset(sum,,sizeof(sum));
has[]=;
for(i=;i<=n;i++)
scanf("%d",&s[i]);
for(i=;i<=n;i++){
sum[i]=(sum[i-]+s[i])%n;
if(has[sum[i]]==-) has[sum[i]]=i;
else{
l=has[sum[i]];
r=i;
}
}
printf("%d\n",r-l);
for(i=l+;i<=r;i++){
printf("%d\n",s[i]);
}
}
return ;
}