47cb6fde79 2013-06-08 kinaba: #include <iostream> 47cb6fde79 2013-06-08 kinaba: #include <sstream> 47cb6fde79 2013-06-08 kinaba: #include <iomanip> 47cb6fde79 2013-06-08 kinaba: #include <vector> 47cb6fde79 2013-06-08 kinaba: #include <string> 47cb6fde79 2013-06-08 kinaba: #include <map> 47cb6fde79 2013-06-08 kinaba: #include <set> 47cb6fde79 2013-06-08 kinaba: #include <algorithm> 47cb6fde79 2013-06-08 kinaba: #include <numeric> 47cb6fde79 2013-06-08 kinaba: #include <iterator> 47cb6fde79 2013-06-08 kinaba: #include <functional> 47cb6fde79 2013-06-08 kinaba: #include <complex> 47cb6fde79 2013-06-08 kinaba: #include <queue> 47cb6fde79 2013-06-08 kinaba: #include <stack> 47cb6fde79 2013-06-08 kinaba: #include <cmath> 47cb6fde79 2013-06-08 kinaba: #include <cassert> 47cb6fde79 2013-06-08 kinaba: using namespace std; 47cb6fde79 2013-06-08 kinaba: typedef long long LL; 47cb6fde79 2013-06-08 kinaba: typedef long double LD; 47cb6fde79 2013-06-08 kinaba: typedef complex<double> CMP; 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: static const int INF = 0x1fffffff; 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: int bitcnt(int x) 47cb6fde79 2013-06-08 kinaba: { 47cb6fde79 2013-06-08 kinaba: int c = 0; 47cb6fde79 2013-06-08 kinaba: for(; x; x>>=1) 47cb6fde79 2013-06-08 kinaba: c += x&1; 47cb6fde79 2013-06-08 kinaba: return c; 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: class YetAnotherBoardGame { public: 47cb6fde79 2013-06-08 kinaba: int g_best; 47cb6fde79 2013-06-08 kinaba: int minimumMoves(vector <string> board) 47cb6fde79 2013-06-08 kinaba: { 47cb6fde79 2013-06-08 kinaba: int H = board.size(); 47cb6fde79 2013-06-08 kinaba: int W = board[0].size(); 47cb6fde79 2013-06-08 kinaba: vector<int> b(H); 47cb6fde79 2013-06-08 kinaba: for(int y=0; y<H; ++y) 47cb6fde79 2013-06-08 kinaba: for(int x=0; x<W; ++x) 47cb6fde79 2013-06-08 kinaba: b[y] |= (board[y][x]=='W')<<x; 47cb6fde79 2013-06-08 kinaba: b.push_back(0); // sentinel 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: g_best = INF; 47cb6fde79 2013-06-08 kinaba: for(int type=1; type<=2; ++type) 47cb6fde79 2013-06-08 kinaba: for(int mask=0; mask<(1<<W); ++mask) 47cb6fde79 2013-06-08 kinaba: { 47cb6fde79 2013-06-08 kinaba: int cur = b[0]; 47cb6fde79 2013-06-08 kinaba: int next = b[1]; 47cb6fde79 2013-06-08 kinaba: flip(cur, next, mask, type, W); 47cb6fde79 2013-06-08 kinaba: do_try(cur, next, b, 1, H, W, (type==1 ? mask : 0), (type==2 ? mask : 0), bitcnt(mask)); 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: return g_best==INF ? -1 : g_best; 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: void flip(int& cur, int& next, int mask, int type, int W) 47cb6fde79 2013-06-08 kinaba: { 47cb6fde79 2013-06-08 kinaba: int pat = (type==1 ? 5 : 7); 47cb6fde79 2013-06-08 kinaba: for(int f=0; (1<<f)<=mask; ++f) 47cb6fde79 2013-06-08 kinaba: if((1<<f) & mask) 47cb6fde79 2013-06-08 kinaba: cur ^= (pat<<f>>1)&((1<<W)-1); 47cb6fde79 2013-06-08 kinaba: next ^= mask; 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: void do_try(int prev, int cur, const vector<int>& b, int y, int H, int W, int must_t1, int must_t2, int acc) 47cb6fde79 2013-06-08 kinaba: { 47cb6fde79 2013-06-08 kinaba: if(y==H) { 47cb6fde79 2013-06-08 kinaba: int score = (prev==0 ? 0 : INF) + acc; 47cb6fde79 2013-06-08 kinaba: g_best = min(g_best, score); 47cb6fde79 2013-06-08 kinaba: return; 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: int mask = prev; 47cb6fde79 2013-06-08 kinaba: int score = bitcnt(mask) + acc; 47cb6fde79 2013-06-08 kinaba: if(score >= g_best) 47cb6fde79 2013-06-08 kinaba: return; 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: if(!(mask&must_t2)) { // try type 1 47cb6fde79 2013-06-08 kinaba: int curr = cur; 47cb6fde79 2013-06-08 kinaba: int next = b[y+1]; 47cb6fde79 2013-06-08 kinaba: flip(curr, next, mask, 1, W); 47cb6fde79 2013-06-08 kinaba: do_try(curr, next, b, y+1, H, W, must_t1|mask, must_t2, score); 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: if(!(mask&must_t1)) { // try type 2 47cb6fde79 2013-06-08 kinaba: int curr = cur; 47cb6fde79 2013-06-08 kinaba: int next = b[y+1]; 47cb6fde79 2013-06-08 kinaba: flip(curr, next, mask, 2, W); 47cb6fde79 2013-06-08 kinaba: do_try(curr, next, b, y+1, H, W, must_t1, must_t2|mask, score); 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: }; 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: // BEGIN CUT HERE 47cb6fde79 2013-06-08 kinaba: #include <ctime> 47cb6fde79 2013-06-08 kinaba: double start_time; string timer() 47cb6fde79 2013-06-08 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 47cb6fde79 2013-06-08 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 47cb6fde79 2013-06-08 kinaba: { os << "{ "; 47cb6fde79 2013-06-08 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 47cb6fde79 2013-06-08 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 47cb6fde79 2013-06-08 kinaba: void verify_case(const int& Expected, const int& Received) { 47cb6fde79 2013-06-08 kinaba: bool ok = (Expected == Received); 47cb6fde79 2013-06-08 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 47cb6fde79 2013-06-08 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 47cb6fde79 2013-06-08 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 47cb6fde79 2013-06-08 kinaba: #define END verify_case(_, YetAnotherBoardGame().minimumMoves(board));} 47cb6fde79 2013-06-08 kinaba: int main(){ 47cb6fde79 2013-06-08 kinaba: 47cb6fde79 2013-06-08 kinaba: CASE(0) 47cb6fde79 2013-06-08 kinaba: string board_[] = {"BBBBBBBBB", 47cb6fde79 2013-06-08 kinaba: "BBWBBBBBB", 47cb6fde79 2013-06-08 kinaba: "BWWWBBBBB", 47cb6fde79 2013-06-08 kinaba: "BBWBBBWBB", 47cb6fde79 2013-06-08 kinaba: "BBBBBWBWB", 47cb6fde79 2013-06-08 kinaba: "BBBBBBWBB"}; 47cb6fde79 2013-06-08 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 47cb6fde79 2013-06-08 kinaba: int _ = 2; 47cb6fde79 2013-06-08 kinaba: END 47cb6fde79 2013-06-08 kinaba: CASE(1) 47cb6fde79 2013-06-08 kinaba: string board_[] = {"BBW", 47cb6fde79 2013-06-08 kinaba: "WWW", 47cb6fde79 2013-06-08 kinaba: "BWW"}; 47cb6fde79 2013-06-08 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 47cb6fde79 2013-06-08 kinaba: int _ = 2; 47cb6fde79 2013-06-08 kinaba: END 47cb6fde79 2013-06-08 kinaba: CASE(2) 47cb6fde79 2013-06-08 kinaba: string board_[] = {"WBW", 47cb6fde79 2013-06-08 kinaba: "BBW", 47cb6fde79 2013-06-08 kinaba: "WBW"}; 47cb6fde79 2013-06-08 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 47cb6fde79 2013-06-08 kinaba: int _ = 4; 47cb6fde79 2013-06-08 kinaba: END 47cb6fde79 2013-06-08 kinaba: CASE(3) 47cb6fde79 2013-06-08 kinaba: string board_[] = {"BBBB", 47cb6fde79 2013-06-08 kinaba: "WBWB", 47cb6fde79 2013-06-08 kinaba: "BBBB", 47cb6fde79 2013-06-08 kinaba: "BBBB"}; 47cb6fde79 2013-06-08 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 47cb6fde79 2013-06-08 kinaba: int _ = -1; 47cb6fde79 2013-06-08 kinaba: END 47cb6fde79 2013-06-08 kinaba: CASE(4) 47cb6fde79 2013-06-08 kinaba: string board_[] = {"WWWWWBW", 47cb6fde79 2013-06-08 kinaba: "WBWBWBW", 47cb6fde79 2013-06-08 kinaba: "BBWBBWW"}; 47cb6fde79 2013-06-08 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 47cb6fde79 2013-06-08 kinaba: int _ = 7; 47cb6fde79 2013-06-08 kinaba: END 47cb6fde79 2013-06-08 kinaba: CASE(5) 47cb6fde79 2013-06-08 kinaba: string board_[] = {"WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW", 47cb6fde79 2013-06-08 kinaba: "WWWWWWWWWW"} 47cb6fde79 2013-06-08 kinaba: ; 47cb6fde79 2013-06-08 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 47cb6fde79 2013-06-08 kinaba: int _ = 30; 47cb6fde79 2013-06-08 kinaba: END 47cb6fde79 2013-06-08 kinaba: /* 47cb6fde79 2013-06-08 kinaba: CASE(6) 47cb6fde79 2013-06-08 kinaba: string board_[] = ; 47cb6fde79 2013-06-08 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 47cb6fde79 2013-06-08 kinaba: int _ = ; 47cb6fde79 2013-06-08 kinaba: END 47cb6fde79 2013-06-08 kinaba: CASE(7) 47cb6fde79 2013-06-08 kinaba: string board_[] = ; 47cb6fde79 2013-06-08 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 47cb6fde79 2013-06-08 kinaba: int _ = ; 47cb6fde79 2013-06-08 kinaba: END 47cb6fde79 2013-06-08 kinaba: */ 47cb6fde79 2013-06-08 kinaba: } 47cb6fde79 2013-06-08 kinaba: // END CUT HERE