【AMPPZ2014】【BZOJ4147】Euclidean Nim

来源:互联网 发布:西门子plc300编程软件 编辑:程序博客网 时间:2024/05/27 16:42

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
原创粉丝点击