1. 程式人生 > >GG and MM HDU

GG and MM HDU

在這裡插入圖片描述 在這裡插入圖片描述 題解: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;
}