您的位置:首页 > 编程语言 > C语言/C++

51Nod 1103 N的倍数

2017-08-28 17:25 288 查看

N的倍数

一个长度为N的数组A,从A中选出若干个数,使得这些数的和是N的倍数。

例如:N = 8,数组A包括:2 5 6 3 18 7 11 19,可以选2 6,因为2 + 6 = 8,是8的倍数。

Input

第1行:1个数N,N为数组的长度,同时也是要求的倍数。(2 <= N <= 50000)

第2 - N + 1行:数组A的元素。(0 < Aii <= 10^9)

Output

如果没有符合条件的组合,输出No Solution。

第1行:1个数S表示你所选择的数的数量。

第2 - S + 1行:每行1个数,对应你所选择的数。

Sample Input

8

2

5

6

3

18

7

11

19

Sample Output

2

2

6

思路:

真的是一道神奇的题目,神奇的算法,听了题解之后五分钟能切完的题目……

首先记录一下每一项的前缀和,然后再记录一下前缀和模n的值。

对于某两项前缀和,若题目模n的值相同,则说明这两项之间的数的和模n为0。

若任意两项前缀和模n的值都不相同,由于一共有n个前缀和,他们%n又都不相同,则余数肯定是0~n-1,也就是说肯定有某项前缀和%n=0。。。

%%%%%%%%%%%%

代码如下:

#include<bits/stdc++.h>
#define ll long long
#define maxn 50005
int n;
ll a[maxn];
ll sum[maxn];
ll mod[maxn];
void solve()
{
int i;
for(i=1;i<=n;i++)
{
if(mod[i]==0)
{
printf("%d\n",i);
int j;
for(j=1;j<=i;j++)
printf("%lld\n",a[j]);
return ;
}
int j;
for(j=1;j<i;j++)
{
if(mod[j]==mod[i])
{
printf("%d\n",i-j);
int k;
for(k=j+1;k<=i;k++)
printf("%lld\n",a[k]);
return ;
}
}
}
}

int main()
{
while(~scanf("%d",&n))
{
int i;
sum[0]=0;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
mod[i]=sum[i]%n;
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言