339e20815a 2014-10-24 kinaba: #include <iostream> 339e20815a 2014-10-24 kinaba: #include <sstream> 339e20815a 2014-10-24 kinaba: #include <iomanip> 339e20815a 2014-10-24 kinaba: #include <vector> 339e20815a 2014-10-24 kinaba: #include <string> 339e20815a 2014-10-24 kinaba: #include <map> 339e20815a 2014-10-24 kinaba: #include <set> 339e20815a 2014-10-24 kinaba: #include <algorithm> 339e20815a 2014-10-24 kinaba: #include <numeric> 339e20815a 2014-10-24 kinaba: #include <iterator> 339e20815a 2014-10-24 kinaba: #include <functional> 339e20815a 2014-10-24 kinaba: #include <complex> 339e20815a 2014-10-24 kinaba: #include <queue> 339e20815a 2014-10-24 kinaba: #include <stack> 339e20815a 2014-10-24 kinaba: #include <cmath> 339e20815a 2014-10-24 kinaba: #include <cassert> 339e20815a 2014-10-24 kinaba: #include <tuple> 339e20815a 2014-10-24 kinaba: using namespace std; 339e20815a 2014-10-24 kinaba: typedef long long LL; 339e20815a 2014-10-24 kinaba: typedef complex<double> CMP; 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: class PathGame { public: 339e20815a 2014-10-24 kinaba: string judge(vector <string> board) 339e20815a 2014-10-24 kinaba: { 339e20815a 2014-10-24 kinaba: vector<int> s; 339e20815a 2014-10-24 kinaba: for(int i=0; i<board[0].size(); ++i) 339e20815a 2014-10-24 kinaba: s.push_back((board[0][i]=='#')+(board[1][i]=='#')*2); 339e20815a 2014-10-24 kinaba: return firstWins(s) ? "Snuke" : "Sothe"; 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: bool firstWins(const vector<int>& s) 339e20815a 2014-10-24 kinaba: { 339e20815a 2014-10-24 kinaba: memo.assign(s.size()*10, -1); 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: vector<int> games; 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: int i = 0; 339e20815a 2014-10-24 kinaba: if(s[0] == 0) 339e20815a 2014-10-24 kinaba: { 339e20815a 2014-10-24 kinaba: int e = find_if(s.begin()+i, s.end(), [&](int v){return v!=0;}) - s.begin(); 339e20815a 2014-10-24 kinaba: int L = 0; 339e20815a 2014-10-24 kinaba: int N = e-i; 339e20815a 2014-10-24 kinaba: int R = e==s.size() ? 0 : s[e]; 339e20815a 2014-10-24 kinaba: games.push_back(grundy(L,N,R)); 339e20815a 2014-10-24 kinaba: i = e; 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: while(i < s.size()) 339e20815a 2014-10-24 kinaba: { 339e20815a 2014-10-24 kinaba: int L = s[i]; 339e20815a 2014-10-24 kinaba: i = find(s.begin()+i, s.end(), 0) - s.begin(); 339e20815a 2014-10-24 kinaba: int e = find_if(s.begin()+i, s.end(), [&](int v){return v!=0;}) - s.begin(); 339e20815a 2014-10-24 kinaba: int N = e-i; 339e20815a 2014-10-24 kinaba: int R = e==s.size() ? 0 : s[e]; 339e20815a 2014-10-24 kinaba: games.push_back(grundy(L,N,R)); 339e20815a 2014-10-24 kinaba: i = e; 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: return xor_all(games) != 0; 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: vector<int> memo; 339e20815a 2014-10-24 kinaba: int grundy(int L, int N, int R) 339e20815a 2014-10-24 kinaba: { 339e20815a 2014-10-24 kinaba: if(N == 0) 339e20815a 2014-10-24 kinaba: return 0; // no move 339e20815a 2014-10-24 kinaba: if(N == 1) { 339e20815a 2014-10-24 kinaba: if(L==0 || R==0 || L==R) 339e20815a 2014-10-24 kinaba: return 1; 339e20815a 2014-10-24 kinaba: return 0; 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: int key = N*9+L*3+R; 339e20815a 2014-10-24 kinaba: if(memo[key] >= 0) 339e20815a 2014-10-24 kinaba: return memo[key]; 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: vector<int> next; 339e20815a 2014-10-24 kinaba: for(int i=0; i<N; ++i) 339e20815a 2014-10-24 kinaba: { 339e20815a 2014-10-24 kinaba: if(i==0) { 339e20815a 2014-10-24 kinaba: if(L!=2) next.push_back(grundy(1,N-1,R)); 339e20815a 2014-10-24 kinaba: if(L!=1) next.push_back(grundy(2,N-1,R)); 339e20815a 2014-10-24 kinaba: } else if(i==N-1) { 339e20815a 2014-10-24 kinaba: if(R!=2) next.push_back(grundy(L,N-1,1)); 339e20815a 2014-10-24 kinaba: if(R!=1) next.push_back(grundy(L,N-1,2)); 339e20815a 2014-10-24 kinaba: } else { 339e20815a 2014-10-24 kinaba: next.push_back(grundy(L,i,1)^grundy(1,N-i-1,R)); 339e20815a 2014-10-24 kinaba: next.push_back(grundy(L,i,2)^grundy(2,N-i-1,R)); 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: return memo[key] = mex(next); 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: int xor_all(const vector<int>& games) 339e20815a 2014-10-24 kinaba: { 339e20815a 2014-10-24 kinaba: int v = 0; 339e20815a 2014-10-24 kinaba: for(int g: games) 339e20815a 2014-10-24 kinaba: v ^= g; 339e20815a 2014-10-24 kinaba: return v; 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: int mex(const vector<int>& games) 339e20815a 2014-10-24 kinaba: { 339e20815a 2014-10-24 kinaba: set<int> gs(games.begin(), games.end()); 339e20815a 2014-10-24 kinaba: for(int v=0;; ++v) 339e20815a 2014-10-24 kinaba: if(gs.count(v)==0) 339e20815a 2014-10-24 kinaba: return v; 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: }; 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: // BEGIN CUT HERE 339e20815a 2014-10-24 kinaba: #include <ctime> 339e20815a 2014-10-24 kinaba: double start_time; string timer() 339e20815a 2014-10-24 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 339e20815a 2014-10-24 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 339e20815a 2014-10-24 kinaba: { os << "{ "; 339e20815a 2014-10-24 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 339e20815a 2014-10-24 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 339e20815a 2014-10-24 kinaba: void verify_case(const string& Expected, const string& Received) { 339e20815a 2014-10-24 kinaba: bool ok = (Expected == Received); 339e20815a 2014-10-24 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 339e20815a 2014-10-24 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 339e20815a 2014-10-24 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 339e20815a 2014-10-24 kinaba: #define END verify_case(_, PathGame().judge(board));} 339e20815a 2014-10-24 kinaba: int main(){ 339e20815a 2014-10-24 kinaba: 339e20815a 2014-10-24 kinaba: CASE(0) 339e20815a 2014-10-24 kinaba: string board_[] = {"#.." 339e20815a 2014-10-24 kinaba: ,"..."}; 339e20815a 2014-10-24 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 339e20815a 2014-10-24 kinaba: string _ = "Snuke"; 339e20815a 2014-10-24 kinaba: END 339e20815a 2014-10-24 kinaba: CASE(1) 339e20815a 2014-10-24 kinaba: string board_[] = {"#" 339e20815a 2014-10-24 kinaba: ,"."}; 339e20815a 2014-10-24 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 339e20815a 2014-10-24 kinaba: string _ = "Sothe"; 339e20815a 2014-10-24 kinaba: END 339e20815a 2014-10-24 kinaba: CASE(2) 339e20815a 2014-10-24 kinaba: string board_[] = {"....." 339e20815a 2014-10-24 kinaba: ,"..#.."}; 339e20815a 2014-10-24 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 339e20815a 2014-10-24 kinaba: string _ = "Sothe"; 339e20815a 2014-10-24 kinaba: END 339e20815a 2014-10-24 kinaba: CASE(3) 339e20815a 2014-10-24 kinaba: string board_[] = {".#..." 339e20815a 2014-10-24 kinaba: ,"....."}; 339e20815a 2014-10-24 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 339e20815a 2014-10-24 kinaba: string _ = "Snuke"; 339e20815a 2014-10-24 kinaba: END 339e20815a 2014-10-24 kinaba: CASE(4) 339e20815a 2014-10-24 kinaba: string board_[] = {".....#..#........##......." 339e20815a 2014-10-24 kinaba: ,"..........#..........#...."}; 339e20815a 2014-10-24 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 339e20815a 2014-10-24 kinaba: string _ = "Snuke"; 339e20815a 2014-10-24 kinaba: END 339e20815a 2014-10-24 kinaba: /* 339e20815a 2014-10-24 kinaba: CASE(5) 339e20815a 2014-10-24 kinaba: string board_[] = ; 339e20815a 2014-10-24 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 339e20815a 2014-10-24 kinaba: string _ = ; 339e20815a 2014-10-24 kinaba: END 339e20815a 2014-10-24 kinaba: CASE(6) 339e20815a 2014-10-24 kinaba: string board_[] = ; 339e20815a 2014-10-24 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 339e20815a 2014-10-24 kinaba: string _ = ; 339e20815a 2014-10-24 kinaba: END 339e20815a 2014-10-24 kinaba: */ 339e20815a 2014-10-24 kinaba: } 339e20815a 2014-10-24 kinaba: // END CUT HERE