题意:
给你N个数,选取任意个数使得和为N的倍数,如果有多组解,输出其中一组满足条件的解就可以了。。
思路:
简单抽屉原理+前缀和处理。
显然假设前缀和数组为sum[i],则sum[i]%n一定会分布在[0,n-1]这个含有N个整点的区间上,然后显然sum[0]=0,因此对于sum[i]%n(0<=i<=n)这n+1个数的值必然至少有两个或以上的点分布在[0,n-1]这个区间上,然后我们再假设j>i,其中sum[j]%n=sum[i]%n,显然则有(sum[j]-sum[i])%n=0也即从第i+1个数到第j个数的和必然能够整除n,因此只要记录每个sum[i]%n的结果分布在哪个点上,一旦找到了两个POS相同的点,然后就可以立刻输出i-pos[sum[i]]个数就OK了。。。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int a[10005];
int sum[10005];
int pos[10005];
int main()
{
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sum[0]=0;
for(int i=1;i<=n;i++)
{
sum[i]=(sum[i-1]+a[i])%n;
}
memset(pos,-1,sizeof(pos));
pos[0]=0;
for(int i=1;i<=n;i++)
{
if(pos[sum[i]]==-1)
{
pos[sum[i]]=i;
}
else
{
cout<<i-pos[sum[i]]<<endl;
for(int j=pos[sum[i]]+1;j<=i;j++)
{
cout<<a[j]<<endl;
}
return 0;
}
}
}
return 0;
}