http://poj.org/problem?id=2356
从n个数里面取出一些数,这些数的和是n的倍数。并输出这些数。
先预处理出前n个数的和用sum[i]表示前i个数的和。若某个sum[i]是n的倍数,直接输出前i个数即可。
否则说明n个数中对n取余的结果有n-1种,即余数为(1~n-1),根据鸽巢原理知必定至少存在两个sum[i]与sum[j]对n取余的结果相等。那么i+1 ~ j之间的数之和一定是n的倍数。
#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
using namespace std;
const int maxn = 10010;
int main()
{
int n;
int a[maxn];
int sum[maxn];
int hash[maxn];
while(~scanf("%d",&n))
{
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
sum[0] = 0;
int i,flag = 0;
memset(hash,-1,sizeof(hash));
for(i = 1; i <= n; i++)
{
sum[i] = (sum[i-1]+a[i])%n;
if(sum[i] == 0)
{
flag = 1;
break;
}
}
if(flag == 1)
{
printf("%d\n",i);
for(int j = 1; j <= i; j++)
printf("%d\n",a[j]);
continue;
}
//for(int i = 1; i <= n; i++)
//printf("sumi : %d\n",sum[i]);
int s,t;
for(int i = 1; i <= n; i++)
{
if(hash[sum[i]] == -1)
hash[sum[i]] = i;
else
{
s = hash[sum[i]];
t = i;
break;
}
}
printf("%d\n",t-s);
for(int i = s+1; i <= t; i++)
{
printf("%d\n",a[i]);
}
}
return 0;
}
与上题类似。只不过是取若干个数的和是m的倍数。跑一遍循环刚好,边哈希sum[i],边判断sum[i]是否等于0,一旦为0就输出,否则直到找到两个相等的sum[i]和sum[j],输出i~j即可。
#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
using namespace std;
const int maxn = 100010;
int n,m;
int a[maxn];
int sum[maxn];
int hash[maxn];
int flag;
int s,t;
int main()
{
while(~scanf("%d %d",&m,&n))
{
if(m == 0 && n == 0) break;
sum[0] = 0;
flag = 0;
memset(hash,-1,sizeof(hash));
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
if(flag) continue;
sum[i] = (sum[i-1]+a[i])%m;
if(sum[i] == 0)
{
flag = 1;
for(int j = 1; j <= i; j++)
{
printf("%d",j);
if(j == i) printf("\n");
else printf(" ");
}
}
else
{
if(hash[sum[i]] == -1)
hash[sum[i]] = i;
else
{
for(int j = hash[sum[i]]+1; j <= i; j++)
{
printf("%d",j);
if(j == i)
printf("\n");
else printf(" ");
}
flag = 1;
}
}
}
}
return 0;
}