4fd800b3a8 2011-02-23 kinaba: #include <iostream> 4fd800b3a8 2011-02-23 kinaba: #include <sstream> 4fd800b3a8 2011-02-23 kinaba: #include <iomanip> 4fd800b3a8 2011-02-23 kinaba: #include <vector> 4fd800b3a8 2011-02-23 kinaba: #include <string> 4fd800b3a8 2011-02-23 kinaba: #include <map> 4fd800b3a8 2011-02-23 kinaba: #include <set> 4fd800b3a8 2011-02-23 kinaba: #include <algorithm> 4fd800b3a8 2011-02-23 kinaba: #include <numeric> 4fd800b3a8 2011-02-23 kinaba: #include <iterator> 4fd800b3a8 2011-02-23 kinaba: #include <complex> 4fd800b3a8 2011-02-23 kinaba: #include <queue> 4fd800b3a8 2011-02-23 kinaba: #include <stack> 4fd800b3a8 2011-02-23 kinaba: #include <cmath> 4fd800b3a8 2011-02-23 kinaba: #include <cstring> 4fd800b3a8 2011-02-23 kinaba: #include <cassert> 4fd800b3a8 2011-02-23 kinaba: using namespace std; 4fd800b3a8 2011-02-23 kinaba: typedef long long LL; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: char memo[81*81*81*81]; 4fd800b3a8 2011-02-23 kinaba: int n, X[16]; 4fd800b3a8 2011-02-23 kinaba: static const char NIL = 99; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: bool win[243]; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: class TheStringGame 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: public: 4fd800b3a8 2011-02-23 kinaba: string winner(string s) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: // construct the winning condition table 4fd800b3a8 2011-02-23 kinaba: for(int mm=0; mm<243; ++mm) 4fd800b3a8 2011-02-23 kinaba: win[mm] = (mm/ 9%3==0 && 4fd800b3a8 2011-02-23 kinaba: ( mm/81%3==2 && mm/27%3==1 // LOX 4fd800b3a8 2011-02-23 kinaba: || mm/27%3==2 && mm/ 3%3==2 // LXL 4fd800b3a8 2011-02-23 kinaba: || mm/ 3%3==1 && mm/ 1%3==2 )); // XOL 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // read the input 4fd800b3a8 2011-02-23 kinaba: int m=0, numX=0; 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: memset(memo, NIL, sizeof(memo)); 4fd800b3a8 2011-02-23 kinaba: n = s.size(); 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i<n; ++i) { 4fd800b3a8 2011-02-23 kinaba: m *= 3; 4fd800b3a8 2011-02-23 kinaba: for(int j=0; j<numX; ++j) 4fd800b3a8 2011-02-23 kinaba: X[j] *= 3; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: if( s[i]=='X' ) 4fd800b3a8 2011-02-23 kinaba: X[numX++] = 1; 4fd800b3a8 2011-02-23 kinaba: else 4fd800b3a8 2011-02-23 kinaba: m += (s[i]=='O' ? 1 : 2); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // solve 4fd800b3a8 2011-02-23 kinaba: if( int r = negaMax(m, numX) ) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: stringstream sout; 4fd800b3a8 2011-02-23 kinaba: sout << (r>0 ? "John" : "Brus") << " " << numX-abs(r)+1; 4fd800b3a8 2011-02-23 kinaba: return sout.str(); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: return "Draw"; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: static int rev(int m) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: int z = 0; 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i<n; ++i) 4fd800b3a8 2011-02-23 kinaba: z = z*3 + m%3, m/=3; 4fd800b3a8 2011-02-23 kinaba: return z; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: static char negaMax(int m, int numX) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: if( numX == 0 ) 4fd800b3a8 2011-02-23 kinaba: return 0; 4fd800b3a8 2011-02-23 kinaba: if( memo[m] != NIL ) 4fd800b3a8 2011-02-23 kinaba: return memo[m]; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: for(int j=0; j<numX; ++j) 4fd800b3a8 2011-02-23 kinaba: if( win[m*9/X[j]%243] ) 4fd800b3a8 2011-02-23 kinaba: return memo[m] = numX; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: int sc = -numX; 4fd800b3a8 2011-02-23 kinaba: for(int j=0; j<numX; ++j) { 4fd800b3a8 2011-02-23 kinaba: int M = X[j]; 4fd800b3a8 2011-02-23 kinaba: swap(X[j], X[numX-1]); 4fd800b3a8 2011-02-23 kinaba: sc = max(sc, -negaMax(m+M*1, numX-1)); 4fd800b3a8 2011-02-23 kinaba: sc = max(sc, -negaMax(m+M*2, numX-1)); 4fd800b3a8 2011-02-23 kinaba: swap(X[j], X[numX-1]); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: return memo[m] = memo[rev(m)] = sc; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: }; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // BEGIN CUT HERE 4fd800b3a8 2011-02-23 kinaba: #include <ctime> 4fd800b3a8 2011-02-23 kinaba: double start_time;string timer() { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } 4fd800b3a8 2011-02-23 kinaba: int verify_case(const string &Expected, const string &Received) { if (Expected == Received) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } return 0;} 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template<int N> struct Case_ { Case_(){start_time=clock();} }; 4fd800b3a8 2011-02-23 kinaba: char Test_(...); 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<0>) { 4fd800b3a8 2011-02-23 kinaba: string s = "XXOXXXLXLX"; 4fd800b3a8 2011-02-23 kinaba: string RetVal = "John 1"; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, TheStringGame().winner(s)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<1>) { 4fd800b3a8 2011-02-23 kinaba: string s = "LXXLXXL"; 4fd800b3a8 2011-02-23 kinaba: string RetVal = "Brus 2"; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, TheStringGame().winner(s)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<2>) { 4fd800b3a8 2011-02-23 kinaba: string s = "LLOOLLOOLLOOLLOO"; 4fd800b3a8 2011-02-23 kinaba: string RetVal = "Draw"; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, TheStringGame().winner(s)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<3>) { 4fd800b3a8 2011-02-23 kinaba: string s = "XXXXXXXXXXXXXXXX"; 4fd800b3a8 2011-02-23 kinaba: string RetVal = "Brus 16"; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, TheStringGame().winner(s)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<4>) { 4fd800b3a8 2011-02-23 kinaba: string s = "XXXXXXXXXXXXXXXO"; 4fd800b3a8 2011-02-23 kinaba: string RetVal = "John 15"; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, TheStringGame().winner(s)); } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template<int N> void Run_() { cerr << "Test Case #" << N << "..." << flush; Test_(Case_<N>()); Run_<sizeof(Test_(Case_<N+1>()))==1 ? -1 : N+1>(); } 4fd800b3a8 2011-02-23 kinaba: template<> void Run_<-1>() {} 4fd800b3a8 2011-02-23 kinaba: int main() { Run_<0>(); } 4fd800b3a8 2011-02-23 kinaba: // END CUT HERE