标签:
在一个2*N的格子上染色 每次可以染1*1的格子 或者2*2的格子 最涂满所有格子的人胜 m为已染色格子的个数 Alice先手
1*1的点SG值为1 SG【i】表示连续2*i的SG值 sg【3】 就是连续2*3空白格子
假如n = 3
涂一个1*1个格子的情况 那么后继状态就可能是
状态1 连续0列的格子+连续2列的格子+剩余那一列涂1个格子
状态2 连续1列的格子+连续1列的格子+剩余那一列涂1个格子
涂一个2*3个格子的情况 那么后继状态就可能是
状态1 连续0列的格子+连续1列的格子+剩余的2*2格子
最后对整个棋盘分段 连续空白的2*i格子 和 某列中涂过色的格子
Sample Input
2
2 0 // n m
2 2 //n m
1 1 //已染色格子的坐标
2 2
Sample Output
Case 1: Alice
Case 2: Bob
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <string> 6 # include <cmath> 7 # include <queue> 8 # include <list> 9 # define LL long long 10 using namespace std ; 11 const int MAXN=5000; 12 int sg[MAXN]; 13 bool vis[MAXN]; 14 bool g[2][MAXN]; 15 int mex(int x) 16 { 17 if(sg[x]!=-1)return sg[x]; 18 memset(vis,false,sizeof(vis)); 19 for(int i=0;i<=x-1-i;i++) //染1*1 20 { 21 int tmp=mex(i)^mex(x-1-i)^1; 22 vis[tmp]=true; 23 } 24 for(int i=0;i<=x-2-i;i++)//染2*2 25 { 26 int tmp=mex(i)^mex(x-2-i); 27 vis[tmp]=true; 28 } 29 for(int i=0;;i++) 30 if(!vis[i]) 31 { 32 sg[x]=i; 33 break; 34 } 35 return sg[x]; 36 } 37 38 int main() 39 { 40 41 memset(sg,-1,sizeof(sg)); 42 sg[0]=0; 43 for(int i=1;i<5000;i++) 44 sg[i]=mex(i); 45 int T; 46 scanf("%d",&T); 47 int iCase=0; 48 while(T--) 49 { 50 int n,m; 51 scanf("%d%d",&n,&m); 52 memset(g,false,sizeof(g)); 53 int u,v; 54 while(m--) 55 { 56 scanf("%d%d",&u,&v); 57 u--;v--; 58 g[u][v]=true; 59 } 60 int len=0; 61 int ans=0; 62 for(int i=0;i<n;i++) 63 { 64 if(g[0][i]||g[1][i]) 65 { 66 ans^=sg[len]; 67 len=0; 68 if(g[0][i]&&g[1][i])continue; 69 ans^=1; 70 } 71 else len++; 72 } 73 ans^=sg[len]; 74 iCase++; 75 if(ans)printf("Case %d: Alice\n",iCase); 76 else printf("Case %d: Bob\n",iCase); 77 } 78 return 0; 79 }
标签:
原文地址:http://www.cnblogs.com/-Buff-/p/4841971.html