POJ 3372 Candy Distribution(数论)

201 篇文章 10 订阅

Description
一群小孩围成一个圈,老师顺时针发糖,分别每间隔0,1, 2, 3, 4……发一颗,问是否每个同学都有糖
Input
多组用例,每组用例占一行包括一个整数n表示小孩人数,以文件尾结束输入
Output
对于每组用例,如果每个小孩都有糖则输出YES,否则输出NO
Sample Input
2
3
4
Sample Output
YES
NO
YES
Solution
将孩子标号0,1,2,…n-1,轻易得出每次得到糖果的孩子标号为f(x)=x*(x+1)/2(mod n),则若是所有孩子都能分到糖果则f(x)必然为n的完全剩余系,即不存在x!=y,使得f(x)=f(y),下面来根据n的值来讨论f(x)是否为n的完全剩余系:
首先给出三个显然的结论
1、任何一个偶数都可以表示成b*2^a的形式
2、(x+y+1)和(x-y)必定一奇一偶
3、若x*y=2^m,则x=2^m1,y=2^m2(0<=m1,m2<=m)
若f(x)=f(y)(不妨令0 <= y < x < n),则x*(x+1)/2-y*(y+1)/2=0(mod n),不妨令g(x,y)=x*(x+1)/2-y*(y+1)/2=(x+y+1)*(x-y)/2,下面就n的值来讨论g(x,y)=tn是否有解
1、当n为奇数时
令x=y+2,则2y+3=n,此时显然存在x=(n+1)/2,y=(n-3)/2(n=1,3时显然f(x)不是n的完全剩余系),使得g(x,y)=n成立,故此时f(x)不是n的完全剩余系
2、当n为偶数且不能被表示成2^a形式时,令n=b*2^a(a>=1,b>1且b为奇数)
(1)当b<2^(a+1)时,不妨令x+y+1=2^(a+1),x-y=b,解此方程组得x=2^a+(b-1)/2 < b*2^a,y=2^a-(b+1)/2 >= 0,显然存在合适的x,y使得g(x,y)=n成立
(2)当b>2^(a+1)时,不妨令x+y+1=b,x-y=2^a,解此方程组得x=2^a+(b-1)/2 < b*2^a,y=(b-1)/2-2^a>=0,显然存在合适的x,y使得g(x,y)=n成立
综(1)(2)可知此时g(x,y)=n有解,即f(x)不是n的完全剩余系
3、当n为偶数且能被表示成2^a形式时
若(x+y+1) * (x-y) / 2=tn,显然t可以表示成c * 2^d(c为奇数,d>=0),故原式可转化为(x+y+1)*(x-y)=c*2^(a+d+1),由结论2可知x+y+1与x-y一奇一偶,下面分两种情况讨论
(1)x+y+1为奇,x-y为偶,此时x+y+1=c,x-y=2^(a+d+1),由y < x < n=2^a知此方程组无解
(2)x+y+1为偶,x-y为奇,此时x+y+1=2^(a+d+1),x-y=c,仍然由y < x < n=2^a可知x+y+1<=2^(a+1)-3<2^(a+d+1),故此方程组无解
综(1)(2)可知此时g(x,y)=tn无解,即f(x)时n的完全剩余系
综上所述,只有当n=2^a时,f(x)才是n的完全剩余系
Code

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if(n&(n-1))printf("NO\n");
        else printf("YES\n");
    }
    return 0;
} 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值