結果
| 問題 |
No.5022 XOR Printer
|
| コンテスト | |
| ユーザー |
prussian_coder
|
| 提出日時 | 2025-07-23 15:09:00 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 247 ms / 2,000 ms |
| コード長 | 4,207 bytes |
| コンパイル時間 | 395 ms |
| コンパイル使用メモリ | 82,376 KB |
| 実行使用メモリ | 80,256 KB |
| スコア | 4,757,586,375 |
| 最終ジャッジ日時 | 2025-07-26 12:41:45 |
| 合計ジャッジ時間 | 13,221 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 50 |
ソースコード
# 貪欲解法2
# ターン数のもとで下記の操作の中で最もスコアが良くなる選択を選ぶ貪欲法
## 現在の位置からマンハッタン距離がdのセルに移動し、操作Wを実施する(d <= 5)
## 現在の位置からマンハッタン距離がd1のセルに移動し操作Cを実施した後、距離d2だけ移動して操作Wを実施する(d1+d2 <= 5)
from __future__ import annotations
import sys
from typing import List, Tuple
Cell = Tuple[int, int]
def move_commands(start: Cell, end: Cell) -> List[str]:
"""Return commands to move from start to end using UDLR moves."""
cmds: List[str] = []
x, y = start
tx, ty = end
while x < tx:
cmds.append("D")
x += 1
while x > tx:
cmds.append("U")
x -= 1
while y < ty:
cmds.append("R")
y += 1
while y > ty:
cmds.append("L")
y -= 1
return cmds
def main() -> None:
n, t = map(int, sys.stdin.readline().split())
board = [list(map(int, sys.stdin.readline().split())) for _ in range(n)]
x, y = 0, 0
s_val = 0
ops: List[str] = []
while len(ops) < t:
remaining = t - len(ops)
best_diff = 0
best_seq: List[str] | None = None
# Option A: move up to distance 5 and write
for dx in range(-5, 6):
for dy in range(-5, 6):
dist = abs(dx) + abs(dy)
if dist == 0 or dist > 5:
continue
nx, ny = x + dx, y + dy
if not (0 <= nx < n and 0 <= ny < n):
continue
cost = dist + 1
if cost > remaining:
continue
diff = (board[nx][ny] ^ s_val) - board[nx][ny]
if diff > best_diff:
best_diff = diff
path = move_commands((x, y), (nx, ny))
best_seq = path + ["W"]
# Option B: move to cell1, copy, move to cell2, write (total dist <= 5)
for dx1 in range(-5, 6):
for dy1 in range(-5, 6):
d1 = abs(dx1) + abs(dy1)
if d1 > 5:
continue
nx1, ny1 = x + dx1, y + dy1
if not (0 <= nx1 < n and 0 <= ny1 < n):
continue
for dx2 in range(-5, 6):
for dy2 in range(-5, 6):
d2 = abs(dx2) + abs(dy2)
if d1 + d2 > 5:
continue
nx2, ny2 = nx1 + dx2, ny1 + dy2
if not (0 <= nx2 < n and 0 <= ny2 < n):
continue
cost = d1 + d2 + 2
if cost > remaining:
continue
s_prime = s_val ^ board[nx1][ny1]
diff = (board[nx2][ny2] ^ s_prime) - board[nx2][ny2]
if diff > best_diff:
best_diff = diff
seq = move_commands((x, y), (nx1, ny1))
seq.append("C")
seq.extend(move_commands((nx1, ny1), (nx2, ny2)))
seq.append("W")
best_seq = seq
if best_seq and best_diff > 0:
ops.extend(best_seq)
# apply operations to board, x, y, s_val
pos_x, pos_y = x, y
for op in best_seq:
if op == "U":
pos_x -= 1
elif op == "D":
pos_x += 1
elif op == "L":
pos_y -= 1
elif op == "R":
pos_y += 1
elif op == "C":
s_val ^= board[pos_x][pos_y]
elif op == "W":
board[pos_x][pos_y] ^= s_val
x, y = pos_x, pos_y
else:
if len(ops) < t:
ops.append("C")
s_val ^= board[x][y]
else:
break
sys.stdout.write("\n".join(ops[:t]) + "\n")
if __name__ == "__main__":
main()
prussian_coder