結果
| 問題 |
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]);
| ~~~~~^~~~~~~~~~~~~~~~~~~
ソースコード
#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;
}
ぴぃいいいい