NYOJ 题目636

世界末日

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 1
描述
世界末日马上就要来临了,当然,每个人都想买到船票,但是由于船票有限,因此需要回答对一个问题才能买票。问题是这样的:给你一个数n (1 <= n <= 10000),之后给n个正整数 (<= 10000),问在这n个数中是否存在一些数的和是n的倍数。
输入
多组测试数据(最多100组)。首先输入一个数n,然后输入n个数。
输出
如果能找到一些数的和是n的倍数,输出"YES",否则输出"NO"。
样例输入
5
5 3 6 7 9
样例输出
YES
抽屉原理
sum[0]=0;
sum[i]=(a[1]+a[2]+a[3]...a[i])%n;
如果存在i>0 使得sum[i]=0;则直接输出a[1],a[2],,....a[i]即可满足题意。
如果不存在,考虑sum[ j ]-sum[ i ]=a [ i+1 ],a[ i+2 ]....a[ j ]。
即如果存在sum[ j ]-sum[ i ]==0,则输出 a [ i+1 ],a[ i+2 ]....a[ j ] 即可。
接下来用抽屉原理证明 i , j 必然存在。
抽屉原理:
如果将大于n个数量的物品放入n个抽屉,则必然存在某个抽屉放了大于1个物品。
因为sum [ i ] 的值只能是1,....n-1.sum [ i ]的数量有n个。
所以由抽屉原理可知,必然存在某两个sum [ i ] 值一样。
n个数:a1,..,an,设c1,..,cn,令c1=a1;c2=a1+a2;cn=a1+a2+...+an;再c1,c2,...,cn对n取模,
若结果中有0,直接yes,若没有0,则对n取模有1,...,n-1个选项,而有n个取模结果,
则至少有两项取模结果是相等的,所以两数相减即是n的倍数,也是一些数的和
这道题一开始写的时候,傻傻的去算、每个数的和的可能,结果自然WA。。。。后来看了别人的提示后,恍然大悟,还能有这种操作,数学真的是博大精深
#include<stdio.h>
int main()
{
    char c[50005];
    while(gets(c))
    {
        gets(c);
        printf("YES\n");
    }
    return 0;
}

发布了45 篇原创文章 · 获赞 1 · 访问量 6797

猜你喜欢

转载自blog.csdn.net/Ls_attack/article/details/75144340