这是一道简单的对鸽笼原理的运用;
题意:给出N个数,从中选出若干个数使得它们的和为N的倍数。
有一种简单的方法如下:
虽然题目没限制怎样选,但是我们可以证明:存在若干个这样的连续数,它们的和是N的倍数。为此,我们可以考察和Sk =a1+a2+...+ak.如果存在一个Sk是N的倍数,那么把前K个数选出来就可以了。否则所有N歌Sk除以N的余数只有1,2,3,4...N-1;这n-1种可能(n-1个盒子),由基本原理 知,必然有两个不同的和Si和Sj(i<j)除以N的余数相同,所以
Sj -Si = ai+1 + .... aj 是N的倍数;


#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> #include<string> #define LL long long using namespace std; int main( ) { int num[10024]; int N,a[10024]; while( scanf( "%d",&N )==1 ){ int sum = 0,flag = 0; memset( num , 0, sizeof( num ) ); for( int i = 1 ; i <= N ; i++ ){ scanf( "%d",&a[i] ); if( flag ) continue; sum += a[i]; int t = sum % N; if( t== 0 ){ flag = 1; printf( "%d\n",i ); for( int j = 1 ; j <= i; j++ ) printf( "%d\n",a[j] ); } else if( num[t] == 0 ) num[t] = i; else{ flag = 1; printf( "%d\n",i - num[t] ); for( int j = num[t]+1 ; j <= i ; j ++ ) printf( "%d\n",a[j] ); } } } //system( "pause" ); return 0; }