鸽巢原理的ppt:
http://wenku.baidu.com/view/a2f20a2458fb770bf78a55b9.html
别人总结的鸽巢原理:
http://blog.youkuaiyun.com/acm_cxlove/article/details/7432166
鸽巢原理:
用s1,s2,s3....sk...sn表示从第一个数到第k个数(包括k)的和
如果sk能整除n,就直接给出结果,否则,将s1到sn对n的余数求出
必有两个余数相同,即si%n == sj%n; 也就(sj-si)%n==0;
所以 i+1 到 j的数的和 就是所求;
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 10000+10;
int a[maxn];
int sum[maxn];
int b[maxn];
int main()
{
int n;
while(cin >> n)
{
sum[0] = 0;
int flag = 0;
for(int i = 1; i <= n; i++) scanf("%d", a+i);
for(int i = 1; i <= n; i++)
{
//scanf("%d", a+i);
if(a[i]%n==0)
{
printf("1\n%d\n", a[i]);
flag = 1;
break;
}
sum[i] = sum[i-1] + a[i];
if(sum[i]%n==0)
{
printf("%d\n", i);
for(int j = 1; j <= i; j++)
printf("%d\n", a[j]);
flag = 1;
break;
}
b[i] = sum[i]%n;
}
if(flag) continue;
for(int i = 1; i <= n; i++)
for(int j = 1; j < i; j++)
{
if(b[i] == b[j])
{
printf("%d\n", i-j);
for(int k = j+1; k <= i; k++)
printf("%d\n", a[k]);
}
}
}
}
poj3370
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100000+10;
__int64 a[maxn] = {0}, b[maxn];
int main()
{
int n, m;
while(scanf("%d%d", &n, &m)!=EOF&&n+m)
{
memset(b, 0, sizeof(b));
bool flag = false;
for(int i = 1; i <= m; i++)
{
int tot;
scanf("%d", &tot);
if(flag) continue;
a[i] = a[i-1] + tot;
if(a[i]%n==0)
{
for(int j = 1; j < i; j++)
printf("%d ", j);
printf("%d\n", i);
flag = true;
}
else if(b[a[i]%n])
{
for(int j = b[a[i]%n]+1; j < i; j++)
printf("%d ", j);
printf("%d\n", i);
flag = true;
}
else b[a[i]%n] = i;
}
}
}