题解:Every_SG
2,Every-SG
定义: 1,Every-SG 游戏规定,对于还没有结束的单一游戏,游戏者必须对该游
戏进行一步决策,也就是每轮操作要对所有单一游戏进行操作。
2,Every-SG 游戏的其他规则与普通SG游戏相同。
定理: 对于Every-SG 游戏先手必胜当且仅当单一游戏中最大的step为奇数。
在通过拓扑关系计算某一个状态点的SG函数时,对于SG值为0的点,我们
需要知道最快几步能将游戏带入终止状态,对于SG值不为0的点,我们需
要知道最慢几步游戏会被带入终止状态,我们用step函数来表示这个值。
#include<iostream>
#include<cstring>
using namespace std;
#define N 2003
int sg[N][N],step[N][N];
int n,m;
int get(int x,int y)
{
if(sg[x][y] != -1) return sg[x][y];
if(x>y) swap(x,y);
int mx = 0,mn = 1e9;
for(int i = x ; i<= y ; i+=x)
{
if(!get(x,y-i))
{
sg[x][y] = sg[y][x] = 1;
mx = max(mx,step[x][y-i]);
}
else mn = min(mn,step[x][y-i]);
}
if(sg[x][y] == 1)
{
step[x][y] = step[y][x] = mx+1;
return sg[x][y];
}
step[x][y] = step[y][x] = mn+1;
sg[x][y] = sg[y][x] = 0;
return sg[x][y];
}
int main()
{
memset(sg,-1,sizeof(sg));
for(int i = 0 ; i < 1000; i++)
{
sg[i][0] = sg[0][i] = step[i][0] = step[0][i] = 0;
}
while(~scanf("%d",&n))
{
int a = 0, b = 0;
for(int i = 1 ; i <= n ; i++)
{
int x,y;
scanf("%d%d",&x,&y);
get(x,y);
if(x == 0||y == 0) continue;
if(sg[x][y]) a = max(a,step[x][y]);
else b = max(b,step[x][y]);
}
if(a>b) puts("MM");
else puts("GG");
}
return 0;
}