#Every-SG#HDU 3595 GG and MM

题目

\(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;
}
posted @ 2021-04-06 07:44  lemondinosaur  阅读(35)  评论(0编辑  收藏  举报