码迷,mamicode.com
首页 > 其他好文 > 详细

TC SRM 637 DIV1 500 PathGame

时间:2016-08-13 19:36:35      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:

Problem Statement

给一个2*1000的board,每个格子黑或者白。白格子从左到右连成一条连接第一列和最后一列的path,path上相邻两格有公共边。两人轮流把白格子涂成黑格子,最后一个被迫涂黑格子使path断开的人输。问先手必胜还是必败。

(Translated By myq_952)

Tutorial

做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 };

TC SRM 637 DIV1 500 PathGame

标签:

原文地址:http://www.cnblogs.com/shinfeb/p/5768628.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!