#include "validate.h" #include using namespace std; const string FAIL = "impossible"; struct unionfind { vector p; int c; unionfind(int n) : p(n, -1), c(n) { } int find(int x) { return p[x] < 0 ? x : p[x] = find(p[x]); } bool united(int x, int y) { return find(x) == find(y); } void unite(int x, int y) { int a = find(x), b = find(y); if(a == b) return; if(p[a] > p[b]) swap(a, b); p[a] += p[b]; p[b] = a; c--; return; } int size(int x) { return -p[find(x)]; } }; int main(int argc, char **argv) { init_io(argc, argv); int n; judge_in >> n; vector input(n); for(int i = 0; i < n; ++i) { judge_in >> input[i]; } string out1; judge_ans >> out1; for(auto& c : out1) c = tolower(c); bool possible = out1 != FAIL; vector ans(n); bool possible_contestant = 1; for(int i = 0; i < n; ++i) { if(!(author_out >> ans[i])) { wrong_answer("Wrong answer: Failed to read enough lines in output.\n"); } if(i == 0){ string lower_ans0 = ans[0]; for(auto& c : lower_ans0) c = tolower(c); if(lower_ans0 == FAIL){ possible_contestant = 0; break; } } } if(possible && !possible_contestant) { wrong_answer("Wrong answer: Said impossible in possible case.\n"); } string trailing; if(author_out >> trailing) { wrong_answer("Wrong answer: Trailing output.\n"); } if(!possible) { accept(); } int a_copper = 0, b_copper = 0; for(int i = 0; i < n; ++i) { if(ans[i].size() != input[i].size()) { wrong_answer("Wrong answer: Pyramidland is not shaped correctly in output.\n"); } for(int j = 0; j < input[i].size(); ++j) { if((ans[i][j] == '#') != (input[i][j] == '#')) { wrong_answer("Wrong answer: # not printed in correct locations in output.\n"); } if(ans[i][j] == '#') continue; if(ans[i][j] != 'A' && ans[i][j] != 'B') { wrong_answer("Wrong answer: Character not equal to #, A or B in output.\n"); } if(input[i][j] == 'C') { if(ans[i][j] == 'A') a_copper++; if(ans[i][j] == 'B') b_copper++; } } } if(a_copper != b_copper) { wrong_answer("Wrong answer: Copper not evenly split between regions in output.\n"); } unionfind uf(n * (2 * n - 1)); for(int i = 0; i < n; ++i) { for(int j = 0; j < 2 * n - 1; ++j) { if(input[i][j] == '#') continue; for(int di = 0; di < 2; ++di) { int i2 = i + (di ? 1 : 0); int j2 = j + (di ? 0 : 1); if(i2 >= n) continue; if(j2 >= 2 * n - 1) continue; if(input[i2][j2] == '#') continue; if(ans[i][j] != ans[i2][j2]) continue; uf.unite(n * j + i, n * j2 + i2); } } } vector a_repr, b_repr; for(int i = 0; i < n; ++i) { for(int j = 0; j < 2 * n - 1; ++j) { if(uf.find(n * j + i) != n * j + i) continue; if(ans[i][j] == 'A') a_repr.push_back(n * j + i); if(ans[i][j] == 'B') b_repr.push_back(n * j + i); } } if(a_repr.size() > 1) { wrong_answer("Wrong answer: Region A not connected in output.\n"); } if(b_repr.size() > 1) { wrong_answer("Wrong answer: Region B not connected in output.\n"); } if(!possible){ judge_error("Jury said impossible but contestant found a solution"); } accept(); }