51nod 1103 N的倍数

来源:互联网 发布:qq在线人数竞猜源码 编辑:程序博客网 时间:2024/05/16 09:22
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示例
825631871119
Output示例
22

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;    }    }}