every-sg的一些知识:
每一个能操作的游戏都要进行操作,谁不能继续操作了谁输。
所以对于一个必输的游戏,那么要尽快的输掉,对于必胜的游戏则要越慢的赢掉。
这里引用一下国家队的论文
https://wenku.baidu.com/view/7cd481e9524de518964b7d1f.html
所以建立一个sg保存胜负,根据上面求一下step即可。
即 若当前为必胜状态,取所有后继状态step的最大值+1;
若当前为必败状态,取所有后继状态step的最小值+1;
不要忘记初始化。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int sg[maxn][maxn];
int step[maxn][maxn];
int Step(int a,int b)
{
if(sg[a][b]!=-1)
return sg[a][b];
if(a>b)
swap(a,b);
int M=-1,Min=0xfffffff;
for(int i=a;i<=b;i+=a)
{
int t=Step(a,b-i);
if(t==0)
{
M=max(M,step[a][b-i]);
sg[a][b]=sg[b][a]=1;
}
else Min=min(Min,step[a][b-i]);
}
if(sg[a][b]==1)
step[a][b]=step[b][a]=M+1;
else
{
step[a][b]=step[b][a]=Min+1;
sg[a][b]=sg[b][a]=0;
}
return sg[a][b];
}
int main()
{
int n,m,x;
int a,b;
int T;
while(cin>>n)
{
memset(sg,-1,sizeof(sg));
int ans=-1;
for(int i=0;i<maxn;i++)
sg[i][0]=sg[0][i]=0,step[i][0]=step[0][i]=0;
for(int i=0;i<n;i++)
{
cin>>a>>b;
Step(a,b);
ans=max(ans,step[a][b]);
}
if(ans%2)
cout<<"MM"<<endl;
else cout<<"GG"<<endl;
}
return 0;
}