#include #include #include #include using namespace std; // 定数定義 const int GRID_SIZE = 10; const int TOTAL_CELLS = 100; const int HALF_CELLS = 50; const int BITS_COUNT = 20; const int EMERGENCY_THRESHOLD = 20; const int GRID_MAX_INDEX = 9; const int SNAKE_WIDTH = 5; // 操作タイプ enum Command { COLLECT = 'C', // 値を取得 WRITE = 'W', // 値を書き込み UP = 'U', // 上移動 DOWN = 'D', // 下移動 LEFT = 'L', // 左移動 RIGHT = 'R' // 右移動 }; // 座標構造体 struct Position { int x, y; Position(int x = 0, int y = 0) : x(x), y(y) {} }; // グローバル変数 int s; // 現在のスコア状態 int t; // 残り操作回数 int n; // 入力パラメータ Position currentPos; // 現在位置 int a[GRID_SIZE][GRID_SIZE]; // グリッドの値 Position route[TOTAL_CELLS]; // 事前計算されたルート // 関数宣言 void moveTo(const Position& target); void executeCommand(Command cmd); // 操作を出力し、操作回数を管理する関数 void executeCommand(Command cmd) { putchar(static_cast(cmd)); putchar('\n'); // 残り操作が緊急闾値になったら特別な終了処理 if (--t == EMERGENCY_THRESHOLD) { Position emergencyPos1(0, 5); Position emergencyPos2(0, 4); moveTo(emergencyPos1); executeCommand(COLLECT); s ^= a[emergencyPos1.x][emergencyPos1.y]; moveTo(emergencyPos2); executeCommand(COLLECT); s ^= a[emergencyPos2.x][emergencyPos2.y]; moveTo(emergencyPos1); executeCommand(WRITE); a[emergencyPos1.x][emergencyPos1.y] ^= s; exit(0); } } // 指定座標に移動する関数 void moveTo(const Position& target) { while (currentPos.y < target.y) { ++currentPos.y; executeCommand(DOWN); } while (currentPos.y > target.y) { --currentPos.y; executeCommand(UP); } while (currentPos.x < target.x) { ++currentPos.x; executeCommand(RIGHT); } while (currentPos.x > target.x) { --currentPos.x; executeCommand(LEFT); } } // インデックスから座標を計算する関数 Position calculatePosition(int q) { if (q >= HALF_CELLS) { // 後半50個は前半の鏡像 Position pos = calculatePosition(q - HALF_CELLS); return Position(GRID_MAX_INDEX - pos.x, GRID_MAX_INDEX - pos.y); } else { // 前半50個の座標計算(蛇行パターン) int x = q / SNAKE_WIDTH; int y = (q / SNAKE_WIDTH % 2) ? (q % SNAKE_WIDTH) : (SNAKE_WIDTH - 1 - q % SNAKE_WIDTH); return Position(x, y); } } int main() { // 入力読み込み scanf("%d", &n); scanf("%d", &t); // 入力はa[行][列]で読み込み、a[x][y]として格納 int temp[GRID_SIZE][GRID_SIZE]; for (int i = 0; i < GRID_SIZE; ++i) { for (int j = 0; j < GRID_SIZE; ++j) { scanf("%d", &temp[i][j]); } } // a[行][列]からa[x][y]に転置 for (int i = 0; i < GRID_SIZE; ++i) { for (int j = 0; j < GRID_SIZE; ++j) { a[j][i] = temp[i][j]; // a[x][y] = temp[y][x] } } // ルートの事前計算 for (int q = 0; q < TOTAL_CELLS; ++q) { route[q] = calculatePosition(q); } // ビット位置ごとの処理(上位ビットから) for (int b = BITS_COUNT - 1; b >= 0; --b) { fprintf(stderr, "b=%d\n", b); // ビットbを立てるための値を探す for (int q = 0; q < TOTAL_CELLS; ++q) { Position pos = route[q]; if ((s ^ a[pos.x][pos.y]) >> b == 1) { moveTo(pos); executeCommand(COLLECT); s ^= a[pos.x][pos.y]; break; } } // ビットbが立っていない場合はスキップ if ((s >> b) != 1) { continue; } // ビットbが0の箇所にsの値を書き込む for (int q = 0; q < TOTAL_CELLS; ++q) { Position pos = route[q]; if (!(a[pos.x][pos.y] >> b & 1)) { moveTo(pos); executeCommand(WRITE); a[pos.x][pos.y] ^= s; } } // 特定位置での追加処理 if (b < BITS_COUNT - 1) { int idx = TOTAL_CELLS - (BITS_COUNT - 1 - b); Position pos = route[idx]; moveTo(pos); executeCommand(WRITE); a[pos.x][pos.y] ^= s; executeCommand(COLLECT); s ^= a[pos.x][pos.y]; } } return 0; }