結果

問題 No.5022 XOR Printer
ユーザー ぴぃいいいい
提出日時 2025-07-29 23:38:19
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 4 ms / 2,000 ms
コード長 4,986 bytes
コンパイル時間 830 ms
コンパイル使用メモリ 81,872 KB
実行使用メモリ 7,720 KB
スコア 5,203,029,102
最終ジャッジ日時 2025-07-29 23:38:23
合計ジャッジ時間 3,792 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 50
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:106:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  106 |     scanf("%d", &n);
      |     ~~~~~^~~~~~~~~~
main.cpp:107:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  107 |     scanf("%d", &t);
      |     ~~~~~^~~~~~~~~~
main.cpp:113:18: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  113 |             scanf("%d", &temp[i][j]);
      |             ~~~~~^~~~~~~~~~~~~~~~~~~

ソースコード

diff #

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <utility>

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<char>(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;
}
0