当前位置: 代码迷 >> 综合 >> 【51NOD 1103 N的倍数】前缀和+鸽巢定理
  详细解决方案

【51NOD 1103 N的倍数】前缀和+鸽巢定理

热度:26   发布时间:2023-12-29 02:42:32.0

51nod1103N的倍数
题意
就是一个长度为N的数组A,从A中选出若干个数,使得这些数的和是N的倍数。
做法
首先肯定要先将所有数对n取个模数,然后想到加和的话,就往前缀和方向想一想,如果我们现在是%n意义下的前缀和,因为%n之后一共有n个取值0-n,如果这n个取值均不相同,那么我们就可以找到那个0的位置,0位置的前缀和%n就是0。如果n个取值中有两个相同,那么这两个位置之间的那段区间的和一定就是n的倍数,所以我们发现不管怎样答案一定存在。
代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 5e4+5;
long long sum[maxn];
long long a[maxn];
int flag[maxn];
int main()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lld",&a[i]);sum[i]=(sum[i-1]+a[i])%n;}for(int i=1;i<=n;i++){if(sum[i]==0){cout<<i<<endl;for(int j=1;j<=i;j++) cout<<a[j]<<endl;return 0;}if(flag[sum[i]]==0) flag[sum[i]]=i;else{cout<<i-flag[sum[i]]<<endl;for(int j=flag[sum[i]]+1;j<=i;j++)  cout<<a[j]<<endl;return 0;}}return 0;
}