标签:
给一个2*1000的board,每个格子黑或者白。白格子从左到右连成一条连接第一列和最后一列的path,path上相邻两格有公共边。两人轮流把白格子涂成黑格子,最后一个被迫涂黑格子使path断开的人输。问先手必胜还是必败。
(Translated By myq_952)
做sg的题有点生(有什么生不生的不就dp嘛)
考虑以一段2*k的全白矩形作为局面,涂黑一个格子会把原局面拆成两个后继局面,然后$n^2$求局面的sg即可
要注意的是,因为本题局面是否合法还和两侧的出口情况有关,所以要分4类讨论(见代码)
另外,既然已以无路可走作为必败态,那么非法局面的sg值就没有意义,要忽略掉==这很重要
我在做的时候,用时间标记的同时调用了其他同样会更新时间标记的函数,导致之间时间标记无效了==这很蒟蒻
1 #include <set> 2 #include <ctime> 3 #include <queue> 4 #include <cstdio> 5 #include <bitset> 6 #include <cctype> 7 #include <bitset> 8 #include <cstdlib> 9 #include <cassert> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 #define inf (1<<30) 14 #define INF (1ll<<62) 15 #define fi first 16 #define se second 17 #define rep(x,s,t) for(register int x=s,t_=t;x<t_;++x) 18 #define per(x,s,t) for(register int x=t-1,s_=s;x>=s_;--x) 19 #define travel(x) for(int I=last[x],to;I&&(to=e[I].to);I=e[I].nxt) 20 #define prt(x) cout<<#x<<":"<<x<<" " 21 #define prtn(x) cout<<#x<<":"<<x<<endl 22 #define pb(x) push_back(x) 23 #define hash asfmaljkg 24 #define rank asfjhgskjf 25 #define y1 asggnja 26 #define y2 slfvm 27 using namespace std; 28 typedef long long ll; 29 typedef pair<int,int> ii; 30 31 string WIN="Snuke"; 32 string LOSE="Sothe"; 33 34 const int maxn=1024; 35 int n; 36 int mark[maxn],allc; 37 struct SG_CIRCLE{ 38 int sg[4][maxn]; 39 void init(){ 40 memset(sg[0],-1,n+1<<2); 41 memset(sg[1],-1,n+1<<2); 42 memset(sg[2],-1,n+1<<2); 43 memset(sg[3],-1,n+1<<2); 44 } 45 int sg0(int x){ 46 if(~sg[0][x])return sg[0][x]; 47 if(x<=1)return sg[0][x]=x; 48 49 rep(i,0,x)sg1(i); 50 51 ++allc; 52 rep(i,0,x)mark[sg1(i)^sg1(x-i-1)]=allc; 53 rep(i,0,maxn)if(mark[i]!=allc) 54 return sg[0][x]=i; 55 } 56 //.... 57 //.... 58 int sg1(int x){ 59 if(~sg[1][x])return sg[1][x]; 60 if(x<=1)return sg[1][x]=x; 61 62 rep(i,0,x)sg1(i),sg2(i),sg3(i); 63 64 ++allc; 65 rep(i,1,x+1){ 66 if(x-i)mark[sg1(i-1)^sg2(x-i)]=allc; 67 mark[sg1(i-1)^sg3(x-i)]=allc; 68 } 69 rep(i,0,maxn)if(mark[i]!=allc) 70 return sg[1][x]=i; 71 } 72 //#... 73 //.... 74 int sg2(int x){ 75 if(~sg[2][x])return sg[2][x]; 76 if(x<=1)return sg[2][x]=0;///不管有没有都输 77 78 rep(i,0,x)sg2(i),sg3(i); 79 80 ++allc; 81 rep(i,2,x+1)mark[sg2(i-1)^sg3(x-i)]=allc; 82 rep(i,0,maxn)if(mark[i]!=allc) 83 return sg[2][x]=i; 84 } 85 //#... 86 //...# 87 int sg3(int x){ 88 if(~sg[3][x])return sg[3][x]; 89 if(x<=1)return sg[3][x]=x; 90 91 rep(i,0,x)sg2(i),sg3(i); 92 93 ++allc; 94 rep(i,1,x+1){ 95 if(i-1&&x-i)mark[sg2(i-1)^sg2(x-i)]=allc; 96 mark[sg3(i-1)^sg3(x-i)]=allc; 97 } 98 rep(i,0,maxn)if(mark[i]!=allc) 99 return sg[3][x]=i; 100 } 101 //#..# 102 //.... 103 }SG; 104 class PathGame { 105 public: 106 string judge(vector <string> d) { 107 n=d[0].length(); 108 109 SG.init(); 110 int ans=0; 111 for(int i=0,j;i<n;i++){ 112 for(j=i;j<n&&d[0][j]==‘.‘&&d[1][j]==‘.‘;j++); 113 if(j==i)continue; 114 if(i==0&&j==n)ans^=SG.sg0(j-i); 115 else if(i==0||j==n)ans^=SG.sg1(j-i); 116 else if(d[0][i-1]^d[0][j])ans^=SG.sg2(j-i); 117 else ans^=SG.sg3(j-i); 118 i=j; 119 } 120 121 return ans?WIN:LOSE; 122 } 123 };
标签:
原文地址:http://www.cnblogs.com/shinfeb/p/5768628.html