#include #include #include #include #include using namespace std; typedef pair pii; // Global game parameters (unchanged during recursion) int N; long long A, B, D, E; // constant parameters a, b, d, e // The mapping of block type to its rotations. // Each block is represented as a vector of (x,y) offsets, where (0,0) is the sign square. unordered_map>> figures_and_rotations{ {0, { { {0,0}, {-1,0}, {-1,-1}, {0,-1} }, { {0,0}, {0,1}, {-1,0}, {-1,1} }, { {0,0}, {0,1}, {1,1}, {1,0} }, { {0,0}, {1,0}, {1,-1}, {0,-1} } }}, {1, { { {0,0}, {0,-1}, {-1,0} }, { {0,0}, {-1,0}, {0,1} }, { {0,0}, {0,1}, {1,0} }, { {0,0}, {0,-1}, {1,0} } }}, {2, { { {0,0}, {0,-1}, {0,-2}, {-1,0} }, { {0,0}, {-1,0}, {-2,0}, {0,1} }, { {0,0}, {0,1}, {0,2}, {1,0} }, { {0,0}, {0,-1}, {1,0}, {2,0} } }}, {3, { { {0,0}, {0,-1}, {0,-2}, {0,-3} }, { {0,0}, {-1,0}, {-2,0}, {-3,0} }, { {0,0}, {0,1}, {0,2}, {0,3} }, { {0,0}, {1,0}, {2,0}, {3,0} } }}, {4, { { {0,0}, {-1,0}, {-2,0}, {-1,-1} }, { {0,0}, {0,1}, {0,2}, {-1,1} }, { {0,0}, {1,0}, {2,0}, {1,1} }, { {0,0}, {0,-1}, {0,-2}, {1,-1} } }} }; // Check if the block (given by its offsets in shape) can be placed with sign square at (i, j) bool canPlace(const vector>& board, int i, int j, const vector& shape) { for (auto& off : shape) { int x = i + off.first; int y = j + off.second; if (x < 0 || x >= N || y < 0 || y >= N || board[x][y]) return false; } return true; } // Given a board, place the block at (i,j) and then clear full rows/columns. // Returns the new board state. vector> simulatePlacement(const vector>& board, int i, int j, const vector& shape) { vector> newBoard = board; // Place the block: mark each cell as occupied. for (auto& off : shape) { int x = i + off.first; int y = j + off.second; newBoard[x][y] = true; } // Check for full rows. vector fullRow(N, true), fullCol(N, true); for (int r = 0; r < N; r++) { for (int c = 0; c < N; c++) { if (!newBoard[r][c]) { fullRow[r] = false; break; } } } for (int c = 0; c < N; c++) { for (int r = 0; r < N; r++) { if (!newBoard[r][c]) { fullCol[c] = false; break; } } } // Clear full rows. for (int r = 0; r < N; r++) { if (fullRow[r]) { for (int c = 0; c < N; c++) { newBoard[r][c] = false; } } } // Clear full columns. for (int c = 0; c < N; c++) { if (fullCol[c]) { for (int r = 0; r < N; r++) { newBoard[r][c] = false; } } } return newBoard; } // Depth-limited DFS that simulates moves ahead. // depth: remaining lookahead depth (1 means only current move is considered) // board: current board state // curr_c, curr_f: current random parameters BEFORE updating for this move. int dfs(int depth, const vector>& board, long long curr_c, long long curr_f) { // Update parameters for next move long long next_c = (curr_c ^ A) + B; long long next_f = (curr_f ^ D) + E; int block_type = next_c % 5; int rot = next_f % 4; const vector& shape = figures_and_rotations[block_type][rot]; int best = 0; bool found = false; // Try every cell as the potential placement for the sign square. for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (canPlace(board, i, j, shape)) { found = true; vector> newBoard = simulatePlacement(board, i, j, shape); int movesMade = 1; if (depth > 1) { movesMade += dfs(depth - 1, newBoard, next_c, next_f); } best = max(best, movesMade); } } } if (!found) return 0; return best; } int main() { ifstream fin("block.in"); ofstream fout("block.out"); long long c, f; fin >> N >> A >> B >> c >> D >> E >> f; // Our board: false indicates an empty cell. vector> board(N, vector(N, false)); // Lookahead depth: we plan 3 moves ahead (including the current move). const int maxDepth = 3; // Store the sequence of moves: each move is the chosen (i, j) for the sign square. vector moves; // Main simulation loop. while (true) { // Update parameters for the current move. c = (c ^ A) + B; f = (f ^ D) + E; int block_type = c % 5; int rot = f % 4; const vector& shape = figures_and_rotations[block_type][rot]; bool moveFound = false; int bestScore = -1; pii bestMove = { -1, -1 }; vector> bestBoard; // Try all possible placements. for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (canPlace(board, i, j, shape)) { moveFound = true; vector> newBoard = simulatePlacement(board, i, j, shape); int score = 1; // this move counts as 1. // Lookahead: simulate next (maxDepth-1) moves. if (maxDepth > 1) { score += dfs(maxDepth - 1, newBoard, c, f); } if (score > bestScore) { bestScore = score; bestMove = { i, j }; bestBoard = newBoard; } } } } if (!moveFound) break; // no valid move available; game ends. // Accept the best move found. moves.push_back(bestMove); board = bestBoard; } // Write the result. Coordinates are output as 1-indexed. fout << moves.size() << "\n"; for (auto& mv : moves) { fout << (mv.first + 1) << " " << (mv.second + 1) << "\n"; } return 0; }