e874ae142a 2015-07-10 kinaba: #include <iostream> e874ae142a 2015-07-10 kinaba: #include <sstream> e874ae142a 2015-07-10 kinaba: #include <iomanip> e874ae142a 2015-07-10 kinaba: #include <vector> e874ae142a 2015-07-10 kinaba: #include <string> e874ae142a 2015-07-10 kinaba: #include <map> e874ae142a 2015-07-10 kinaba: #include <set> e874ae142a 2015-07-10 kinaba: #include <algorithm> e874ae142a 2015-07-10 kinaba: #include <numeric> e874ae142a 2015-07-10 kinaba: #include <iterator> e874ae142a 2015-07-10 kinaba: #include <functional> e874ae142a 2015-07-10 kinaba: #include <complex> e874ae142a 2015-07-10 kinaba: #include <queue> e874ae142a 2015-07-10 kinaba: #include <stack> e874ae142a 2015-07-10 kinaba: #include <cmath> e874ae142a 2015-07-10 kinaba: #include <cassert> e874ae142a 2015-07-10 kinaba: #include <tuple> e874ae142a 2015-07-10 kinaba: using namespace std; e874ae142a 2015-07-10 kinaba: typedef long long LL; e874ae142a 2015-07-10 kinaba: typedef complex<double> CMP; e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: class Balance { public: e874ae142a 2015-07-10 kinaba: string canTransform(vector <string> initial, vector <string> target) e874ae142a 2015-07-10 kinaba: { e874ae142a 2015-07-10 kinaba: auto ti = gen_tree(initial); e874ae142a 2015-07-10 kinaba: auto tt = gen_tree(target); e874ae142a 2015-07-10 kinaba: return tree_eq(ti, tt) ? "Possible" : "Impossible"; e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: vector<vector<int>> gen_tree(vector<string> s) { e874ae142a 2015-07-10 kinaba: s.push_back(string(s[0].size(), '#')); e874ae142a 2015-07-10 kinaba: s.insert(s.begin(), string(s[0].size(), '#')); e874ae142a 2015-07-10 kinaba: for(auto& si: s) e874ae142a 2015-07-10 kinaba: si = '#'+si+'#'; e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: const int H = s.size(), W = s[0].size(); e874ae142a 2015-07-10 kinaba: const int NOTYET = 0x7fffffff; e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: vector<vector<int>> tree; e874ae142a 2015-07-10 kinaba: vector<vector<int>> parent_cand(H, vector<int>(W, -1)); e874ae142a 2015-07-10 kinaba: vector<vector<int>> color(H, vector<int>(W, NOTYET)); e874ae142a 2015-07-10 kinaba: for(int y=0; y<H; ++y) e874ae142a 2015-07-10 kinaba: for(int x=0; x<W; ++x) e874ae142a 2015-07-10 kinaba: if(color[y][x]==NOTYET) { e874ae142a 2015-07-10 kinaba: const char ME = s[y][x]; e874ae142a 2015-07-10 kinaba: int newId = tree.size(); e874ae142a 2015-07-10 kinaba: tree.resize(newId+1); e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: // BFS e874ae142a 2015-07-10 kinaba: set<int> tonari; e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: queue<pair<int,int>> Q; e874ae142a 2015-07-10 kinaba: color[y][x] = newId; e874ae142a 2015-07-10 kinaba: Q.emplace(y, x); e874ae142a 2015-07-10 kinaba: while(!Q.empty()) { e874ae142a 2015-07-10 kinaba: int yy = Q.front().first; e874ae142a 2015-07-10 kinaba: int xx = Q.front().second; e874ae142a 2015-07-10 kinaba: Q.pop(); e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: int dx[] = {-1,+1,0,0}; e874ae142a 2015-07-10 kinaba: int dy[] = {0,0,-1,+1}; e874ae142a 2015-07-10 kinaba: for(int d=0; d<4; ++d) { e874ae142a 2015-07-10 kinaba: int y2 = yy+dy[d]; e874ae142a 2015-07-10 kinaba: int x2 = xx+dx[d]; e874ae142a 2015-07-10 kinaba: if(0<=x2&&x2<W&&0<=y2&&y2<H) { e874ae142a 2015-07-10 kinaba: if(s[y2][x2]==ME&&color[y2][x2]==NOTYET) { e874ae142a 2015-07-10 kinaba: color[y2][x2] = newId; e874ae142a 2015-07-10 kinaba: Q.emplace(y2, x2); e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: if(s[y2][x2]!=ME&&color[y2][x2]!=NOTYET) { e874ae142a 2015-07-10 kinaba: tonari.insert(color[y2][x2]); e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: if(tonari.size() == 1) e874ae142a 2015-07-10 kinaba: tree[*tonari.begin()].push_back(newId); e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: return tree; e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: map<vector<int>, int> hashId; e874ae142a 2015-07-10 kinaba: bool tree_eq(const vector<vector<int>>& a, const vector<vector<int>>& b) e874ae142a 2015-07-10 kinaba: { e874ae142a 2015-07-10 kinaba: return hash(a,0) == hash(b,0); e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: int hash(const vector<vector<int>>& a, int r) e874ae142a 2015-07-10 kinaba: { e874ae142a 2015-07-10 kinaba: vector<int> ch; e874ae142a 2015-07-10 kinaba: for(int v: a[r]) e874ae142a 2015-07-10 kinaba: ch.push_back(hash(a, v)); e874ae142a 2015-07-10 kinaba: sort(ch.begin(), ch.end()); e874ae142a 2015-07-10 kinaba: if(hashId.count(ch)) e874ae142a 2015-07-10 kinaba: return hashId[ch]; e874ae142a 2015-07-10 kinaba: int v = hashId.size(); e874ae142a 2015-07-10 kinaba: return hashId[ch] = v; e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: }; e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: // BEGIN CUT HERE e874ae142a 2015-07-10 kinaba: #include <ctime> e874ae142a 2015-07-10 kinaba: double start_time; string timer() e874ae142a 2015-07-10 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } e874ae142a 2015-07-10 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) e874ae142a 2015-07-10 kinaba: { os << "{ "; e874ae142a 2015-07-10 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) e874ae142a 2015-07-10 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } e874ae142a 2015-07-10 kinaba: void verify_case(const string& Expected, const string& Received) { e874ae142a 2015-07-10 kinaba: bool ok = (Expected == Received); e874ae142a 2015-07-10 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; e874ae142a 2015-07-10 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } e874ae142a 2015-07-10 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); e874ae142a 2015-07-10 kinaba: #define END verify_case(_, Balance().canTransform(initial, target));} e874ae142a 2015-07-10 kinaba: int main(){ e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: CASE(0) e874ae142a 2015-07-10 kinaba: string initial_[] = {"#"}; e874ae142a 2015-07-10 kinaba: vector <string> initial(initial_, initial_+sizeof(initial_)/sizeof(*initial_)); e874ae142a 2015-07-10 kinaba: string target_[] = {"."}; e874ae142a 2015-07-10 kinaba: vector <string> target(target_, target_+sizeof(target_)/sizeof(*target_)); e874ae142a 2015-07-10 kinaba: string _ = "Impossible"; e874ae142a 2015-07-10 kinaba: END e874ae142a 2015-07-10 kinaba: CASE(1) e874ae142a 2015-07-10 kinaba: string initial_[] = {"..", e874ae142a 2015-07-10 kinaba: ".."}; e874ae142a 2015-07-10 kinaba: vector <string> initial(initial_, initial_+sizeof(initial_)/sizeof(*initial_)); e874ae142a 2015-07-10 kinaba: string target_[] = {".#", e874ae142a 2015-07-10 kinaba: "##"}; e874ae142a 2015-07-10 kinaba: vector <string> target(target_, target_+sizeof(target_)/sizeof(*target_)); e874ae142a 2015-07-10 kinaba: string _ = "Possible"; e874ae142a 2015-07-10 kinaba: END e874ae142a 2015-07-10 kinaba: CASE(2) e874ae142a 2015-07-10 kinaba: string initial_[] = {"...", e874ae142a 2015-07-10 kinaba: ".#.", e874ae142a 2015-07-10 kinaba: "..."}; e874ae142a 2015-07-10 kinaba: vector <string> initial(initial_, initial_+sizeof(initial_)/sizeof(*initial_)); e874ae142a 2015-07-10 kinaba: string target_[] = {"###", e874ae142a 2015-07-10 kinaba: "#.#", e874ae142a 2015-07-10 kinaba: "###"}; e874ae142a 2015-07-10 kinaba: vector <string> target(target_, target_+sizeof(target_)/sizeof(*target_)); e874ae142a 2015-07-10 kinaba: string _ = "Impossible"; e874ae142a 2015-07-10 kinaba: END e874ae142a 2015-07-10 kinaba: CASE(3) e874ae142a 2015-07-10 kinaba: string initial_[] = {".#.#.......", e874ae142a 2015-07-10 kinaba: "####.###...", e874ae142a 2015-07-10 kinaba: ".....####..", e874ae142a 2015-07-10 kinaba: "..##.#.##.#", e874ae142a 2015-07-10 kinaba: ".##..#.##.#", e874ae142a 2015-07-10 kinaba: ".#######...", e874ae142a 2015-07-10 kinaba: ".#....###.#", e874ae142a 2015-07-10 kinaba: ".##.#.#....", e874ae142a 2015-07-10 kinaba: "..#...#...#", e874ae142a 2015-07-10 kinaba: "..#####...#", e874ae142a 2015-07-10 kinaba: "..........."}; e874ae142a 2015-07-10 kinaba: vector <string> initial(initial_, initial_+sizeof(initial_)/sizeof(*initial_)); e874ae142a 2015-07-10 kinaba: string target_[] = {"...........", e874ae142a 2015-07-10 kinaba: ".###....#..", e874ae142a 2015-07-10 kinaba: ".#.#..#....", e874ae142a 2015-07-10 kinaba: ".###.......", e874ae142a 2015-07-10 kinaba: ".#####.....", e874ae142a 2015-07-10 kinaba: ".#...#####.", e874ae142a 2015-07-10 kinaba: ".#.#.....#.", e874ae142a 2015-07-10 kinaba: ".#.#####.#.", e874ae142a 2015-07-10 kinaba: ".#.......#.", e874ae142a 2015-07-10 kinaba: ".#########.", e874ae142a 2015-07-10 kinaba: "..........."}; e874ae142a 2015-07-10 kinaba: vector <string> target(target_, target_+sizeof(target_)/sizeof(*target_)); e874ae142a 2015-07-10 kinaba: string _ = "Impossible"; e874ae142a 2015-07-10 kinaba: END e874ae142a 2015-07-10 kinaba: CASE(4) e874ae142a 2015-07-10 kinaba: string initial_[] = {".....", e874ae142a 2015-07-10 kinaba: ".###.", e874ae142a 2015-07-10 kinaba: ".....", e874ae142a 2015-07-10 kinaba: ".###.", e874ae142a 2015-07-10 kinaba: "....."}; e874ae142a 2015-07-10 kinaba: vector <string> initial(initial_, initial_+sizeof(initial_)/sizeof(*initial_)); e874ae142a 2015-07-10 kinaba: string target_[] = {".....", e874ae142a 2015-07-10 kinaba: ".#.#.", e874ae142a 2015-07-10 kinaba: ".#.#.", e874ae142a 2015-07-10 kinaba: ".#.#.", e874ae142a 2015-07-10 kinaba: "....."}; e874ae142a 2015-07-10 kinaba: vector <string> target(target_, target_+sizeof(target_)/sizeof(*target_)); e874ae142a 2015-07-10 kinaba: string _ = "Possible"; e874ae142a 2015-07-10 kinaba: END e874ae142a 2015-07-10 kinaba: /* e874ae142a 2015-07-10 kinaba: CASE(5) e874ae142a 2015-07-10 kinaba: string initial_[] = ; e874ae142a 2015-07-10 kinaba: vector <string> initial(initial_, initial_+sizeof(initial_)/sizeof(*initial_)); e874ae142a 2015-07-10 kinaba: string target_[] = ; e874ae142a 2015-07-10 kinaba: vector <string> target(target_, target_+sizeof(target_)/sizeof(*target_)); e874ae142a 2015-07-10 kinaba: string _ = ; e874ae142a 2015-07-10 kinaba: END e874ae142a 2015-07-10 kinaba: CASE(6) e874ae142a 2015-07-10 kinaba: string initial_[] = ; e874ae142a 2015-07-10 kinaba: vector <string> initial(initial_, initial_+sizeof(initial_)/sizeof(*initial_)); e874ae142a 2015-07-10 kinaba: string target_[] = ; e874ae142a 2015-07-10 kinaba: vector <string> target(target_, target_+sizeof(target_)/sizeof(*target_)); e874ae142a 2015-07-10 kinaba: string _ = ; e874ae142a 2015-07-10 kinaba: END e874ae142a 2015-07-10 kinaba: */ e874ae142a 2015-07-10 kinaba: e874ae142a 2015-07-10 kinaba: } e874ae142a 2015-07-10 kinaba: // END CUT HERE