/******************************************************* Problem - Can you win the (bah) game? Solution by - Sean Falconer Algorithm: There's more than one way to solve this, but the technique I used was backtracking. Basically, this tries all possible solutions and early outs on invalid partial solutions. To try all possible solutions, we just need to try our octagons on every side. Another, less general, solution would be to write 6 embedded loops, each looping over all 8 possible sides of the octagons and test side matches. *******************************************************/ #include #include using namespace std; #define ROWS 2 #define COLS 3 // Octagon object struct Octagon { int sides[8], tpos; Octagon() : tpos(0) {} // utility functions to get matching sides with an offset int getTop() { return sides[tpos]; } int getRight() { return sides[(tpos+2)%8]; } int getBottom() { return sides[(tpos+4)%8]; } int getLeft() { return sides[(tpos+6)%8]; } void print() { for(int i = 0; i < 8; i++) { if(i) cout << " "; cout << sides[(tpos+i)%8]; } cout << endl; } }; Octagon grid[ROWS][COLS]; // the problem says they only know primes up to 41, so hard code them int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41}; int isprime[42]; // mark of primes for fast lookup void precompute() { for(int i = 0; i < 42; i++) isprime[i] = 0; for(int i = 0; i < 13; i++) isprime[primes[i]] = 1; } // print my octagons void printOcts() { for(int r = 0; r < ROWS; r++) for(int c = 0; c < COLS; c++) { grid[r][c].print(); } } // check if a configuration is valid bool isValid(int r, int c, int p) { grid[r][c].tpos = p; for(int i = 0; i < 2; i++) { int nr = r, nc = c; if(i == 0) nr--; else if(i == 1) nc--; if(nr < 0 || nr >= ROWS || nc < 0 || nc >= COLS) continue; if(i == 0 && !isprime[grid[r][c].getTop() + grid[nr][nc].getBottom()]) return false; else if(i == 1 && !isprime[grid[r][c].getLeft() + grid[nr][nc].getRight()]) return false; } return true; } // backtrack to find a solution bool canSolve(int r, int c) { if(r == ROWS) return true; // try all possible rotations for(int i = 0; i < 8; i++) if(isValid(r, c, i)) { int nr = r, nc = c; if(c < COLS - 1) nc++; else { nc = 0; nr++; } if(canSolve(nr, nc)) return true; } return false; } int main() { precompute(); // precompute list of primes int T; cin >> T; for(int i = 0; i < T; i++) { if(i) cout << endl; // print separating blank line // read input for(int r = 0; r < ROWS; r++) for(int c = 0; c < COLS; c++) { for(int j = 0; j < 8; j++) cin >> grid[r][c].sides[j]; } // solve problem if possible if(canSolve(0, 0)) printOcts(); else cout << "Cannot win" << endl; } return 0; }