結果
| 問題 |
No.228 ゆきこちゃんの 15 パズル
|
| コンテスト | |
| ユーザー |
gew1fw
|
| 提出日時 | 2025-06-12 21:24:05 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 45 ms / 5,000 ms |
| コード長 | 3,480 bytes |
| コンパイル時間 | 359 ms |
| コンパイル使用メモリ | 81,912 KB |
| 実行使用メモリ | 54,016 KB |
| 最終ジャッジ日時 | 2025-06-12 21:25:27 |
| 合計ジャッジ時間 | 2,041 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 17 |
ソースコード
import sys
from collections import deque
def main():
# Read the target grid
target_grid = []
for _ in range(4):
row = list(map(int, sys.stdin.readline().split()))
target_grid.append(row)
# Determine the initial positions of each tile
initial_pos = {}
for i in range(4):
for j in range(4):
if i == 3 and j == 3:
initial_pos[0] = (i+1, j+1)
else:
tile = 1 + i*4 + j
initial_pos[tile] = (i+1, j+1)
# Determine the target positions of each tile
target_pos = {}
for i in range(4):
for j in range(4):
tile = target_grid[i][j]
target_pos[tile] = (i+1, j+1)
# Determine the set S of tiles that need to be moved
S = set()
for tile in range(1, 16):
if initial_pos[tile] != target_pos[tile]:
S.add(tile)
# Target empty position
T = target_pos[0]
# If no tiles need to be moved, output Yes
if not S:
print("Yes")
return
# Directions for empty space movement (up, down, left, right)
directions = [(-1,0), (1,0), (0,-1), (0,1)]
# BFS initialization
# Each state is (empty_i, empty_j, frozenset(remaining_tiles))
initial_state = (4,4, frozenset(S))
visited = set()
visited.add(initial_state)
queue = deque()
queue.append(initial_state)
while queue:
current = queue.popleft()
empty_i, empty_j, remaining = current
# Check if we've reached the target state
if (empty_i, empty_j) == T and len(remaining) == 0:
print("Yes")
return
# Explore all possible moves
for di, dj in directions:
ni = empty_i + di
nj = empty_j + dj
if 1 <= ni <= 4 and 1 <= nj <= 4:
# Determine the tile that would be moved into the empty space
tile = target_grid[ni-1][nj-1] if (ni, nj) in [(empty_i + di, empty_j + dj)] else None
# Wait, no. The initial grid of the target is not relevant here.
# Instead, the tile is the one at (ni, nj) in the initial grid.
# So, get the tile's position in the initial grid.
for t in initial_pos:
if initial_pos[t] == (ni, nj):
tile = t
break
else:
tile = None
if tile is None:
continue
# Check if the tile is in the remaining set
if tile not in remaining:
continue
# Check if the tile's target position is the current empty position
if target_pos[tile] != (empty_i, empty_j):
continue
# Create the new remaining set
new_remaining = set(remaining)
new_remaining.remove(tile)
new_remaining_frozen = frozenset(new_remaining)
# Check if this new state has been visited
new_state = (ni, nj, new_remaining_frozen)
if new_state not in visited:
visited.add(new_state)
queue.append(new_state)
# If BFS completes without finding a solution
print("No")
if __name__ == "__main__":
main()
gew1fw