您的位置:首页 > 其它

51nod 1103 N的倍数

2017-09-19 16:44 169 查看
1103 N的倍数


题目来源: Ural 1302

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题


收藏


关注

一个长度为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

好坑啊..这是一道特解题,及时答案与案例不一样也是可以过的....
碰到这种一串数列求和相关的,一般都是要用到前缀和的。把前缀和求出来,在思考。
情况1:前缀和%N正好等于0.也就是直接找出答案了,直接输出即可
情况2:如果两个前缀和相等,那么他们相减,也就是他们中间的部分即为答案
可能有人问万一都不是这两种情况呢,比如5  :1 2 4 7 7. 那么我们要去1,4的呀.  其实我们要注意每个前缀和都%n。那么每一位都是0-n-1的。
根据抽屉原理,n的抽屉,n-1种苹果,所以必然有两个抽屉是一样的。 所以一定存在两个前缀和%n之后相等。 所以这道题一定有解,不存在no
solution 的情况。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <list>
#include <algorithm>
using namespace std;
const int mm=5e4+10;
int a[mm];
long long S[mm];
int l,r;
int main()
{
int n;
S[0]=0;
scanf("%d",&n);
int flag=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
S[i]=S[i-1]+a[i];
S[i]%=n;
if(S[i]==0)
{
flag=i;
}
}
if(flag)
{
cout<<flag<<endl;
for(int i=1;i<=flag;i++)
{
printf("%d\n",a[i]);

}
}
else
{

for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(S[j]==S[i])
{
flag=1;
l=i+1;
r=j;
break;
}
}
if(flag)
break;
}
if(flag)
{
printf("%d\n",r-l+1);
for(int i=l;i<=r;i++)
printf("%d\n",a[i]);
}
else
{
cout<<"No Solution"<<endl;
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: