【抽屉定理】 组合数学poj2356

假定n个数为a1,a2,...,an,前n项和分别是S1、S2、...、Sn,
那么如果有一个Si模n是0,就是答案,
否则,n个数模n的余数只能在 1到n - 1之间,
把余数作为抽屉,显然n个数放到n - 1个抽屉里面,
肯定有两个数余数相等,这样取它们的差就得到了结果,
算法复杂度是O(n)的。

 

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

using namespace std;

#define maxn 10005

int n;

int s[maxn];

int sum[maxn];

int pos[maxn];

void input()

{

    scanf("%d",&n);

    for (int i=1;i<=n;i++)

        scanf("%d",&s[i]);

    sum[0]=s[0]=0;

    for (int i=1;i<=n;i++)

        sum[i]=(sum[i-1]+s[i])%n;

}

void work()

{

    memset(pos,-1,sizeof(pos));

    pos[0]=0;

    for (int i=1;i<=n;i++)

        if (pos[sum[i]]==-1)

            pos[sum[i]]=i;

        else

        {

            printf("%d\n",i-pos[sum[i]]);

            for (int j=pos[sum[i]]+1;j<=i;j++)

                printf("%d\n",s[j]);

            return;

        }

}

int main()

{

    freopen("in.txt", "r", stdin);

    input();

    work();

    return 0;

}

 

你可能感兴趣的:(poj)