f3a2b05988 2013-10-15 kinaba: #include <iostream> f3a2b05988 2013-10-15 kinaba: #include <sstream> f3a2b05988 2013-10-15 kinaba: #include <iomanip> f3a2b05988 2013-10-15 kinaba: #include <vector> f3a2b05988 2013-10-15 kinaba: #include <string> f3a2b05988 2013-10-15 kinaba: #include <map> f3a2b05988 2013-10-15 kinaba: #include <set> f3a2b05988 2013-10-15 kinaba: #include <algorithm> f3a2b05988 2013-10-15 kinaba: #include <numeric> f3a2b05988 2013-10-15 kinaba: #include <iterator> f3a2b05988 2013-10-15 kinaba: #include <functional> f3a2b05988 2013-10-15 kinaba: #include <complex> f3a2b05988 2013-10-15 kinaba: #include <queue> f3a2b05988 2013-10-15 kinaba: #include <stack> f3a2b05988 2013-10-15 kinaba: #include <cmath> f3a2b05988 2013-10-15 kinaba: #include <cassert> f3a2b05988 2013-10-15 kinaba: #include <tuple> f3a2b05988 2013-10-15 kinaba: using namespace std; f3a2b05988 2013-10-15 kinaba: typedef long long LL; f3a2b05988 2013-10-15 kinaba: typedef complex<double> CMP; f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: class HexagonalBoard { public: f3a2b05988 2013-10-15 kinaba: typedef pair<int,int> vert; f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: int minColors(vector <string> board) f3a2b05988 2013-10-15 kinaba: { f3a2b05988 2013-10-15 kinaba: int H = board.size(); f3a2b05988 2013-10-15 kinaba: int W = board[0].size(); f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: map<vert, vector<vert>> G; f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: bool has_edge = false; f3a2b05988 2013-10-15 kinaba: for(int y=0; y<H; ++y) f3a2b05988 2013-10-15 kinaba: for(int x=0; x<W; ++x) if(board[y][x]=='X') { f3a2b05988 2013-10-15 kinaba: G[vert(y,x)]; f3a2b05988 2013-10-15 kinaba: for(int Y=0; Y<H; ++Y) f3a2b05988 2013-10-15 kinaba: for(int X=0; X<W; ++X) if(board[Y][X]=='X') f3a2b05988 2013-10-15 kinaba: if(juxt(y,x,Y,X)) { f3a2b05988 2013-10-15 kinaba: has_edge = true; f3a2b05988 2013-10-15 kinaba: G[vert(y,x)].emplace_back(Y,X); f3a2b05988 2013-10-15 kinaba: } f3a2b05988 2013-10-15 kinaba: } f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: if(G.empty()) f3a2b05988 2013-10-15 kinaba: return 0; f3a2b05988 2013-10-15 kinaba: if(!has_edge) f3a2b05988 2013-10-15 kinaba: return 1; f3a2b05988 2013-10-15 kinaba: return two(G) ? 2 : 3; f3a2b05988 2013-10-15 kinaba: } f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: bool juxt(int y, int x, int Y, int X) f3a2b05988 2013-10-15 kinaba: { f3a2b05988 2013-10-15 kinaba: if(y==Y && x==X) f3a2b05988 2013-10-15 kinaba: return false; f3a2b05988 2013-10-15 kinaba: if(y==Y) f3a2b05988 2013-10-15 kinaba: return abs(x-X) == 1; f3a2b05988 2013-10-15 kinaba: if(y+1==Y) f3a2b05988 2013-10-15 kinaba: return x-1==X || x==X; f3a2b05988 2013-10-15 kinaba: if(Y+1==y) f3a2b05988 2013-10-15 kinaba: return X-1==x || X==x; f3a2b05988 2013-10-15 kinaba: return false; f3a2b05988 2013-10-15 kinaba: } f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: bool two(map<vert, vector<vert>>& G) f3a2b05988 2013-10-15 kinaba: { f3a2b05988 2013-10-15 kinaba: map<vert, int> C; f3a2b05988 2013-10-15 kinaba: for(auto it=G.begin(); it!=G.end(); ++it) f3a2b05988 2013-10-15 kinaba: if(!C.count(it->first)) f3a2b05988 2013-10-15 kinaba: if(!rec(it->first, G, C, 0)) f3a2b05988 2013-10-15 kinaba: return false; f3a2b05988 2013-10-15 kinaba: return true; f3a2b05988 2013-10-15 kinaba: } f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: bool rec(vert v, map<vert, vector<vert>>& G, map<vert,int>& C, int c) f3a2b05988 2013-10-15 kinaba: { f3a2b05988 2013-10-15 kinaba: if(C.count(v)) f3a2b05988 2013-10-15 kinaba: return C[v] == c; f3a2b05988 2013-10-15 kinaba: C[v] = c; f3a2b05988 2013-10-15 kinaba: auto& ne = G[v]; f3a2b05988 2013-10-15 kinaba: for(int i=0; i<ne.size(); ++i) f3a2b05988 2013-10-15 kinaba: if(!rec(ne[i], G, C, c^1)) f3a2b05988 2013-10-15 kinaba: return false; f3a2b05988 2013-10-15 kinaba: return true; f3a2b05988 2013-10-15 kinaba: } f3a2b05988 2013-10-15 kinaba: }; f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: // BEGIN CUT HERE f3a2b05988 2013-10-15 kinaba: #include <ctime> f3a2b05988 2013-10-15 kinaba: double start_time; string timer() f3a2b05988 2013-10-15 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } f3a2b05988 2013-10-15 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) f3a2b05988 2013-10-15 kinaba: { os << "{ "; f3a2b05988 2013-10-15 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) f3a2b05988 2013-10-15 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } f3a2b05988 2013-10-15 kinaba: void verify_case(const int& Expected, const int& Received) { f3a2b05988 2013-10-15 kinaba: bool ok = (Expected == Received); f3a2b05988 2013-10-15 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; f3a2b05988 2013-10-15 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } f3a2b05988 2013-10-15 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); f3a2b05988 2013-10-15 kinaba: #define END verify_case(_, HexagonalBoard().minColors(board));} f3a2b05988 2013-10-15 kinaba: int main(){ f3a2b05988 2013-10-15 kinaba: f3a2b05988 2013-10-15 kinaba: CASE(0) f3a2b05988 2013-10-15 kinaba: string board_[] = {"---", f3a2b05988 2013-10-15 kinaba: "---", f3a2b05988 2013-10-15 kinaba: "---"} f3a2b05988 2013-10-15 kinaba: ; f3a2b05988 2013-10-15 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); f3a2b05988 2013-10-15 kinaba: int _ = 0; f3a2b05988 2013-10-15 kinaba: END f3a2b05988 2013-10-15 kinaba: CASE(1) f3a2b05988 2013-10-15 kinaba: string board_[] = {"-X--", f3a2b05988 2013-10-15 kinaba: "---X", f3a2b05988 2013-10-15 kinaba: "----", f3a2b05988 2013-10-15 kinaba: "-X--"}; f3a2b05988 2013-10-15 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); f3a2b05988 2013-10-15 kinaba: int _ = 1; f3a2b05988 2013-10-15 kinaba: END f3a2b05988 2013-10-15 kinaba: CASE(2) f3a2b05988 2013-10-15 kinaba: string board_[] = {"XXXX", f3a2b05988 2013-10-15 kinaba: "---X", f3a2b05988 2013-10-15 kinaba: "---X", f3a2b05988 2013-10-15 kinaba: "---X"}; f3a2b05988 2013-10-15 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); f3a2b05988 2013-10-15 kinaba: int _ = 2; f3a2b05988 2013-10-15 kinaba: END f3a2b05988 2013-10-15 kinaba: CASE(3) f3a2b05988 2013-10-15 kinaba: string board_[] = {"XX-XX--" f3a2b05988 2013-10-15 kinaba: ,"-XX-XXX" f3a2b05988 2013-10-15 kinaba: ,"X-XX--X" f3a2b05988 2013-10-15 kinaba: ,"X--X-X-" f3a2b05988 2013-10-15 kinaba: ,"XX-X-XX" f3a2b05988 2013-10-15 kinaba: ,"-X-XX-X" f3a2b05988 2013-10-15 kinaba: ,"-XX-XX-"}; f3a2b05988 2013-10-15 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); f3a2b05988 2013-10-15 kinaba: int _ = 3; f3a2b05988 2013-10-15 kinaba: END f3a2b05988 2013-10-15 kinaba: /* f3a2b05988 2013-10-15 kinaba: CASE(4) f3a2b05988 2013-10-15 kinaba: string board_[] = ; f3a2b05988 2013-10-15 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); f3a2b05988 2013-10-15 kinaba: int _ = ; f3a2b05988 2013-10-15 kinaba: END f3a2b05988 2013-10-15 kinaba: CASE(5) f3a2b05988 2013-10-15 kinaba: string board_[] = ; f3a2b05988 2013-10-15 kinaba: vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); f3a2b05988 2013-10-15 kinaba: int _ = ; f3a2b05988 2013-10-15 kinaba: END f3a2b05988 2013-10-15 kinaba: */ f3a2b05988 2013-10-15 kinaba: } f3a2b05988 2013-10-15 kinaba: // END CUT HERE