这题嘛……刚开始写的超时的程序。后来发现是用鸽笼原理来做的。
总共有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; }