URAL 1032 Find a Multiple

URAL_1032

    这个题目不像网上有些人说的“需要选连续的数,是因为翻译的问题”,因为可以证明这个题目一定有解,而且可以证明一定存在一个选择连续的数的解。

    不妨设a[i]为第i个数,A[i]=(a[1]+a[2]+…+a[i])%N,这样首先如果A[i]=0那么选择前i个数就可以了,如果不存在A[i]=0,那么A[i]的取值范围就缩小到了1~N-1,那么必然有两个不同的数x、y(x<y)使得A[x]=A[y],那么就有A[y]-A[x]=(a[x]+a[x+1]+…+a[y])%N=0,于是将第x个至第y个数选出来即可。

    于是我们接下来要做的就是去找令A[x]=A[y]的x和y(可以补上A[0]=0,这样如果A[i]=0可以认为x为0,y为i)。

#include<stdio.h>

#include<string.h>

#define MAXD 10010

int N, a[MAXD], A[MAXD], h[MAXD];

void init()

{

    int i;

    A[0] = 0;

    for(i = 1; i <= N; i ++)

    {

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

        A[i] = (A[i - 1] + a[i]) % N;

    }

}

void print(int x, int y)

{

    int i;

    printf("%d\n", y - x + 1);

    for(i = x; i <= y; i ++)

        printf("%d\n", a[i]);

}

void solve()

{

    int i;

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

    h[0] = 0;

    for(i = 1; i <= N; i ++)

    {

        if(h[A[i]] != -1)

        {

            print(h[A[i]] + 1, i);

            return ;

        }

        h[A[i]] = i;

    }

}

int main()

{

    while(scanf("%d", &N) == 1)

    {

        init();

        solve();

    }

    return 0;

}

你可能感兴趣的:(find)