题目
有\(n\)个游戏,每个游戏只要能进行就必须进行,
对于每个游戏有两堆石子,每次可以将数量多的中取出小堆石子数量的整数倍,
无法操作者为负,问先手是否必胜
分析
如果单个游戏最大操作次数为奇数次先手必胜,
如果当前局面为必败局面,必须尽量缩短步数,否则尽量延长步数,
若\(x<y,\lfloor\frac{y}{x}\rfloor>1\)先手必胜,步数由\(sg[y\pmod x][x]\)决定,
否则需要\(sg[y\pmod x][x]\)决定先手胜负
代码
#include <cstdio>
#define rr register
using namespace std;
const int N=1011;
int step[N][N],sg[N][N],n;
inline signed max(int a,int b){return a>b?a:b;}
signed main(){
for (rr int i=1;i<N;++i)
for (rr int j=1;j<=i;++j)
if (i/j==1) step[j][i]=step[i%j][j]+1,sg[j][i]=sg[i%j][j]^1;
else step[j][i]=step[i%j][j]+sg[i%j][j]+(sg[j][i]=1);
while (scanf("%d",&n)==1){
rr int ans=0;
for (rr int i=1,x,y;i<=n;++i){
scanf("%d%d",&x,&y);
if (x>y) x^=y,y^=x,x^=y;
ans=max(ans,step[x][y]);
}
puts(ans&1?"MM":"GG");
}
return 0;
}