这题嘛……刚开始写的超时的程序。后来发现是用鸽笼原理来做的。
总共有N个数。
输入的数据存为 a[1] a[2] .........a[N]
令 b[n]=(a[1]+a[2]+a[3]+...+a[n])%N (n=1,2,3,...,N)
b[0]=0;
首先,b[n]都是N的余数。总共有N个取值(0,1,2,...,N-1)
而 b[0],b[1],b[2],...,b[N]共有N+1个数。
根据鸽笼原理,必存在 i < j 使得 b[ i ]=b[ j ] ,即前 i 个数的和的余数等于前 j 个数的和的余数,则从 第 i+1个数到第 j 个数的和的余数=0;
则 a[ i+1],a[ i+2],...,a[ j ] 即为所求。
代码如下
int a[10001];
int b[10001];
int c[10000];
int N;
int main(void)
{
while(cin>>N){
//输入
memset(c,0,sizeof(c));
b[0]=0;c[0]++;
for(int i=1;i<=N;i++){
scanf("%d",&a[i]);
b[i]=(b[i-1]+a[i])%N;
c[b[i]]++;
}
int T=0;
//找到相同的余数值
int same,l=-1,r=-1;
for(int i=0;i<10000;i++){
if(c[i]>=2){
same=i;//存在两个余数都为i
break;
}
}
//找到l和r
for(int i=0;i<=N;i++){//搜索所有的余数
if(b[i]==same){//如果余数对了,则记录 i
if(~l) {
if(~r) break;
else r=i;
}
else l=i;
}
}
//输出
if(~l&&~r){
printf("%d\n",r-l);
for(int j=l+1;j<=r;j++){
printf("%d\n",a[j]);
}
}
else{
printf("%d\n",0);
}
}
return 0;
}