51Nod 1103 N的倍数

1103 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 < A[i] <= 10^9)
Output
如果没有符合条件的组合,输出No Solution。
第1行:1个数S表示你所选择的数的数量。
第2 - S + 1行:每行1个数,对应你所选择的数。
Input示例
8
2
5
6
3
18
7
11
19
Output示例
2
2
6


抽屉原理 求前缀和 % n
前缀和 b[i]==0 或者 b[j]-b[i]==0 则找到一组解
根据抽屉原理 必定有解

(代码又丑还很长,其实还有更简单的写法,我懒得写)

 1 #include <cstdio>
 2 #include <cctype>
 3 
 4 const int MAXN=50010;
 5 
 6 int n,p;
 7 
 8 int a[MAXN],b[MAXN],ans[MAXN][110];
 9 
10 inline void read(int&x) {
11     int f=1;register char c=getchar();
12     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
13     for(;isdigit(c);x=x*10+c-48,c=getchar());
14     x=x*f;
15 }
16 
17 int hh() {
18     read(n);
19     for(int i=1;i<=n;++i) 
20       read(a[i]),b[i]=(a[i]+b[i-1])%n,ans[b[i]][++ans[b[i]][0]]=i;
21     if(ans[0][0]) {
22         printf("%d
",ans[0][1]);
23         for(int i=1;i<=ans[0][1];++i)
24           printf("%d
",a[i]);
25     }
26     else 
27     for(int i=0;i<n;++i) {
28         if(ans[i][0]>=2) {
29             printf("%d
",ans[i][2]-ans[i][1]);
30             for(int j=ans[i][1]+1;j<=ans[i][2];++j)
31               printf("%d
",a[j]);
32             break;
33         }
34     }
35     return 0;
36 }
37 
38 int sb=hh();
39 int main(int aegc,char**argv) {;}
代码



原文地址:https://www.cnblogs.com/whistle13326/p/7538040.html