题意:
求在长度为 (n) 的数组中选择连续的元素,使其和是 (n) 的倍数,输出元素个数和每个元素的值。
分析:
我们选取一段连续的元素。对原数组求前缀和,并且对 (n) 取模,那么结果就会分布在 ([0,n)) 之间。如果有一个前缀和取模 (n) 的结果为 (0),那么这个前缀和一定满足条件。否则,我们考虑有 (n) 个结果,分布在长度为 (n-1) 的区间上,根据鸽巢原理,必然会有两个相同,那么这两个位置之间的元素和就满足条件。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e4+5;
ll a[N],vis[N];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
memset(vis,0,sizeof(vis));
int p=1,q=n;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
ll sum=0;
for(int i=1;i<=n;i++)
{
sum+=a[i];
if(sum%n==0)
{
p=1;
q=i;
break;
}
else if(vis[sum%n]!=0)
{
p=vis[sum%n]+1;
q=i;
break;
}
else
vis[sum%n]=i;
}
printf("%d
",q-p+1);
for(int i=p;i<=q;i++)
printf("%lld
",a[i]);
}
return 0;
}