#include #include #include #include #include using namespace std; typedef long long ll; // Размери на дъската и параметри на играта int N; ll a, b, c, d, e, f; // Дефиниция на блокчетата const int MAX_PIECE_SIZE = 5; // Структура за представяне на блокче struct Piece { int size; int positions[MAX_PIECE_SIZE][2]; // Относителни позиции спрямо знаковото квадратче int signalIdx; // Индекс на знаковото квадратче }; // Дъската за игра bool board[26][26]; // Петте основни блокчета Piece pieces[5]; // Инициализация на блокчетата void initializePieces() { // Блокче 0: Единично квадратче pieces[0].size = 1; pieces[0].positions[0][0] = 0; pieces[0].positions[0][1] = 0; pieces[0].signalIdx = 0; // Блокче 1: Хоризонтална линия от 4 квадратчета pieces[1].size = 4; for (int i = 0; i < 4; i++) { pieces[1].positions[i][0] = 0; pieces[1].positions[i][1] = i; } pieces[1].signalIdx = 0; // Блокче 2: L-образно блокче pieces[2].size = 3; pieces[2].positions[0][0] = 0; pieces[2].positions[0][1] = 0; pieces[2].positions[1][0] = 0; pieces[2].positions[1][1] = 1; pieces[2].positions[2][0] = 1; pieces[2].positions[2][1] = 0; pieces[2].signalIdx = 0; // Блокче 3: T-образно блокче pieces[3].size = 4; pieces[3].positions[0][0] = 0; pieces[3].positions[0][1] = 0; pieces[3].positions[1][0] = 0; pieces[3].positions[1][1] = 1; pieces[3].positions[2][0] = 0; pieces[3].positions[2][1] = 2; pieces[3].positions[3][0] = 1; pieces[3].positions[3][1] = 1; pieces[3].signalIdx = 1; // Блокче 4: квадрат 2x2 pieces[4].size = 4; pieces[4].positions[0][0] = 0; pieces[4].positions[0][1] = 0; pieces[4].positions[1][0] = 0; pieces[4].positions[1][1] = 1; pieces[4].positions[2][0] = 1; pieces[4].positions[2][1] = 0; pieces[4].positions[3][0] = 1; pieces[4].positions[3][1] = 1; pieces[4].signalIdx = 0; } // Ротация на блокче void rotatePiece(Piece& piece, int rotation) { // rotation = 0, 1, 2, 3 (съответно 0°, 90°, 180°, 270°) if (rotation == 0) return; // Няма ротация for (int i = 0; i < piece.size; i++) { int x = piece.positions[i][0]; int y = piece.positions[i][1]; for (int r = 0; r < rotation; r++) { // Ротация на 90° по часовниковата стрелка int tmp = x; x = y; y = -tmp; } piece.positions[i][0] = x; piece.positions[i][1] = y; } } // Нормализиране на блокче след ротация (да нямаме отрицателни координати) void normalizePiece(Piece& piece) { int minX = 100, minY = 100; for (int i = 0; i < piece.size; i++) { minX = min(minX, piece.positions[i][0]); minY = min(minY, piece.positions[i][1]); } for (int i = 0; i < piece.size; i++) { piece.positions[i][0] -= minX; piece.positions[i][1] -= minY; } } // Проверка дали блокчето може да се постави на дъската bool canPlacePiece(const Piece& piece, int row, int col) { // Намираме позицията на знаковото квадратче int signalRow = row; int signalCol = col; // Проверяваме всички квадратчета на блокчето for (int i = 0; i < piece.size; i++) { int newRow = signalRow + piece.positions[i][0] - piece.positions[piece.signalIdx][0]; int newCol = signalCol + piece.positions[i][1] - piece.positions[piece.signalIdx][1]; // Проверка за излизане извън дъската if (newRow < 1 || newRow > N || newCol < 1 || newCol > N) { return false; } // Проверка за колизия с други блокчета if (board[newRow][newCol]) { return false; } } return true; } // Поставяне на блокчето на дъската void placePiece(const Piece& piece, int row, int col) { int signalRow = row; int signalCol = col; for (int i = 0; i < piece.size; i++) { int newRow = signalRow + piece.positions[i][0] - piece.positions[piece.signalIdx][0]; int newCol = signalCol + piece.positions[i][1] - piece.positions[piece.signalIdx][1]; board[newRow][newCol] = true; } } // Проверка дали ред е пълен bool isRowFull(int row) { for (int col = 1; col <= N; col++) { if (!board[row][col]) { return false; } } return true; } // Проверка дали колона е пълна bool isColFull(int col) { for (int row = 1; row <= N; row++) { if (!board[row][col]) { return false; } } return true; } // Изчистване на пълни редове и колони void clearFullLines() { vector fullRows, fullCols; // Намиране на пълни редове for (int row = 1; row <= N; row++) { if (isRowFull(row)) { fullRows.push_back(row); } } // Намиране на пълни колони for (int col = 1; col <= N; col++) { if (isColFull(col)) { fullCols.push_back(col); } } // Изчистване на пълни редове for (int row : fullRows) { for (int col = 1; col <= N; col++) { board[row][col] = false; } } // Изчистване на пълни колони for (int col : fullCols) { for (int row = 1; row <= N; row++) { board[row][col] = false; } } } // Следващо блокче и ротация според правилата void getNextPieceAndRotation(int& pieceType, int& rotation) { c = (c ^ a) + b; f = (f ^ d) + e; pieceType = c % 5; rotation = f % 4; } // Основен алгоритъм за намиране на възможно най-дълга последователност от валидни ходове vector> findLongestSequence() { vector> moves; memset(board, 0, sizeof(board)); while (true) { int pieceType, rotation; getNextPieceAndRotation(pieceType, rotation); // Създаваме копие на текущото блокче Piece currentPiece = pieces[pieceType]; // Прилагаме ротация rotatePiece(currentPiece, rotation); normalizePiece(currentPiece); // Опитваме се да поставим блокчето на всяка възможна позиция bool placed = false; for (int row = 1; row <= N && !placed; row++) { for (int col = 1; col <= N && !placed; col++) { if (canPlacePiece(currentPiece, row, col)) { placePiece(currentPiece, row, col); moves.push_back({row, col}); clearFullLines(); placed = true; } } } if (!placed) { // Ако блокчето не може да се постави никъде, приключваме break; } } return moves; } int main() { ifstream fin("block.in"); ofstream fout("block.out"); fin >> N >> a >> b >> c >> d >> e >> f; initializePieces(); vector> moves = findLongestSequence(); fout << moves.size() << endl; for (const auto& move : moves) { fout << move.first << " " << move.second << endl; } fin.close(); fout.close(); return 0; }