結果
| 問題 |
No.228 ゆきこちゃんの 15 パズル
|
| コンテスト | |
| ユーザー |
gew1fw
|
| 提出日時 | 2025-06-12 16:35:42 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,967 bytes |
| コンパイル時間 | 260 ms |
| コンパイル使用メモリ | 82,116 KB |
| 実行使用メモリ | 56,728 KB |
| 最終ジャッジ日時 | 2025-06-12 16:35:50 |
| 合計ジャッジ時間 | 6,912 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 2 WA * 1 TLE * 1 -- * 13 |
ソースコード
import sys
from itertools import permutations
from collections import deque
def main():
# Read input and setup initial and target positions
initial_pos = {}
target_pos = {}
zero_initial = (3, 3) # Initial empty position (0-based)
zero_target = None
# Initialize initial positions (standard 15-puzzle)
cnt = 1
for i in range(4):
for j in range(4):
if cnt <= 15:
initial_pos[cnt] = (i, j)
cnt += 1
# Read target configuration
target = []
for i in range(4):
row = list(map(int, sys.stdin.readline().split()))
for j, num in enumerate(row):
if num == 0:
zero_target = (i, j)
else:
target_pos[num] = (i, j)
target.extend(row)
# Check standard solvability condition
target_list = [num for num in target if num != 0]
inv_count = 0
for i in range(len(target_list)):
for j in range(i+1, len(target_list)):
if target_list[i] > target_list[j]:
inv_count += 1
row_initial = zero_initial[0]
row_target = zero_target[0]
row_diff = row_initial - row_target
if (inv_count % 2) != (abs(row_diff) % 2):
print("No")
return
# Check Manhattan distance for each tile
possible = True
for num in range(1, 16):
if num not in initial_pos or num not in target_pos:
continue
ix, iy = initial_pos[num]
tx, ty = target_pos[num]
if abs(ix - tx) + abs(iy - ty) > 1:
possible = False
break
if not possible:
print("No")
return
# Collect pieces that need to be moved
move_pieces = []
for num in range(1, 16):
if initial_pos[num] != target_pos[num]:
move_pieces.append(num)
if not move_pieces:
print("Yes")
return
# BFS function to check path from current empty to target position avoiding obstacles
def bfs(start, goal, obstacles):
visited = [[False]*4 for _ in range(4)]
q = deque()
q.append((start[0], start[1]))
visited[start[0]][start[1]] = True
dirs = [(-1,0), (1,0), (0,-1), (0,1)]
while q:
x, y = q.popleft()
if (x, y) == goal:
return True
for dx, dy in dirs:
nx, ny = x + dx, y + dy
if 0 <= nx < 4 and 0 <= ny < 4:
if not visited[nx][ny] and (nx, ny) not in obstacles:
visited[nx][ny] = True
q.append((nx, ny))
return False
# Check each permutation of move_pieces
for perm in permutations(move_pieces):
current_empty = zero_initial
moved = set()
valid = True
for piece in perm:
init_x, init_y = initial_pos[piece]
# Possible adjacent positions to the piece's initial position
adjacent = []
for dx, dy in [(-1,0), (1,0), (0,-1), (0,1)]:
nx, ny = init_x + dx, init_y + dy
if 0 <= nx < 4 and 0 <= ny < 4:
adjacent.append((nx, ny))
# Determine obstacles (unmoved pieces' initial positions)
obstacles = set()
for p in move_pieces:
if p not in moved and p != piece:
px, py = initial_pos[p]
obstacles.add((px, py))
# Check if any adjacent position is reachable
found = False
for adj in adjacent:
if bfs(current_empty, adj, obstacles):
current_empty = (init_x, init_y)
moved.add(piece)
found = True
break
if not found:
valid = False
break
if valid:
print("Yes")
return
print("No")
if __name__ == "__main__":
main()
gew1fw