【AMPPZ2014】【BZOJ4147】Euclidean Nim

Description
Euclid和Pythagoras在玩取石子游戏,一开始有n颗石子。
Euclid为先手,他们按如下规则轮流操作:
·若为Euclid操作,如果n< p,则他只能新放入p颗石子,否则他可以拿走p的倍数颗石子。
·若为Pythagoras操作,如果n< q,则他只能新放入q颗石子,否则他可以拿走q的倍数颗石子。
拿光所有石子者胜利。假设他们都以最优策略操作,那么获胜者是谁?

Input
第一行包含一个正整数t(1<=t<=1000),表示数据组数。
接下来t行,每行三个正整数p,q,n(1<=p,q,n<=10^9),表示一组数据。

Output
输出t行。第i行输出第i组数据的答案,如果Euclid必胜,输出E,如果Pythagoras必胜,输出P,
如果游戏永远不会停止,输出R。

Sample Input
4
3 2 1
2 3 1
3 4 5
2 4 3

Sample Output
P
P
E
R
HINT

在第一组数据中,Euclid必须新放入3颗石子,然后Pythagoras拿走4颗石子并获胜。

Source

鸣谢Claris上传

好玩的博弈..还可以放石子
不需要SG函数.
结论
如果gcd(p,q)不整除n,则永远不会停止
若p==q,则p必胜
否则p,q,n/=gcd,假设p< q
若q是先手且n< q,则q必败
若p是先手且n>=p,则p必胜
若p是先手且n< p,则当(q-p)|n时p必败,否则p必胜
若q是先手且n>=q,设z=n%q,若(q-p)|z且z< p,则q必胜否则q必败
证明:Po姐的证明

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int T;
int n,p,q;
int gcd(int a,int b)
{
    return !b?a:gcd(b,a%b);
}
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d%d",&p,&q,&n);
        int tmp=gcd(p,q);
        if (n%tmp!=0)   {puts("R");continue;}
        if (p==q)   {puts("E");continue;}
        p/=tmp;q/=tmp;n/=tmp;
        if (p<q)
        {
            if (n>=p)   {puts("E");continue;}
            if (n%(q-p)==0) puts("P");
            else    puts("E");
        }
        else
        {
            if (n<p)    {puts("P");continue;}
            int t=n%p;
            if (t%(p-q)==0&&t<q)    puts("E");
            else    puts("P");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值