51Nod 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\n",ans[0][1]); 23 for(int i=1;i<=ans[0][1];++i) 24 printf("%d\n",a[i]); 25 } 26 else 27 for(int i=0;i<n;++i) { 28 if(ans[i][0]>=2) { 29 printf("%d\n",ans[i][2]-ans[i][1]); 30 for(int j=ans[i][1]+1;j<=ans[i][2];++j) 31 printf("%d\n",a[j]); 32 break; 33 } 34 } 35 return 0; 36 } 37 38 int sb=hh(); 39 int main(int aegc,char**argv) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现