D - 迷宮からの脱出 / Escape from the Labyrinth 解説 by admin 印刷ページ
Qwen3-Coder-480BOverview
This is a problem where Takahashi must escape from a maze containing security robots in the minimum number of turns. Since the security robots move based on Takahashi’s position, we need to perform a search while simulating the movements of both parties.
Analysis
In this problem, we need to consider not only Takahashi’s movements but also the security robots’ movements that respond to his position. A simple breadth-first search (BFS) would include wasteful paths that visit the same cell multiple times, so we need to manage the state as “Takahashi’s position” combined with “all security robots’ positions.”
Furthermore, since the security robots’ movements are determined by Takahashi’s position, the order in which they move is important — robots move after Takahashi moves. The robots’ movements are deterministic, with their destination chosen according to Manhattan distance and a predetermined priority order.
Additionally, since the constraints are very small (\(N, M \leq 8\), \(K \leq 2\)), it is possible to explore all states, making exhaustive search via BFS effective.
Algorithm
This problem is solved using BFS with states (stateful BFS).
State Definition
- Turn number
- Takahashi’s position \((r, c)\)
- Each security robot’s position (up to 2), held as a tuple
Search Flow
- Add the initial state (turn 1, Takahashi’s initial position, security robots’ initial positions) to the queue and register it in the visited set.
- Dequeue a state and move Takahashi to each reachable cell.
- If Takahashi is caught by a security robot after moving, discard that path.
- If the exit is reached, output that turn number and terminate.
- Move the security robots, then perform another capture check.
- If the new state (Takahashi’s new position + robots’ new positions) has not been visited, increment the turn number and add it to the queue.
- Repeat until the queue is empty; if the exit is never reached, output
-1.
Security robots move in the direction that minimizes the Manhattan distance to Takahashi’s new position, following a predetermined priority order.
Complexity
The grid size is at most \(8 \times 8 = 64\) cells, and there are at most 2 security robots, so the number of combinations for robot positions is at most \(64^2 = 4096\). Takahashi’s position also has 64 possibilities. Therefore, the total number of states is approximately \(64 \times 4096 = 262144\), which is well within the range that BFS can handle.
- Time complexity: \(O(NM \cdot (NM)^K \cdot 5)\) (5 represents Takahashi’s movement choices)
- Space complexity: \(O(NM \cdot (NM)^K)\)
Implementation Notes
Convert the coordinate system to 0-indexed (input is 1-indexed).
In the security robot movement function, implement selection of the direction that minimizes Manhattan distance with the highest priority.
Include the turn number, player position, and robot positions in the BFS state.
Use a visited set to avoid re-exploring the same state (player position + robot positions).
Use a
dequefor the queue to perform the search efficiently.Source Code
from collections import deque
import sys
def main():
import sys
input = sys.stdin.read
data = input().split()
idx = 0
N = int(data[idx]); idx += 1
M = int(data[idx]); idx += 1
K = int(data[idx]); idx += 1
Sr = int(data[idx]) - 1; idx += 1
Sc = int(data[idx]) - 1; idx += 1
Gr = int(data[idx]) - 1; idx += 1
Gc = int(data[idx]) - 1; idx += 1
guards = []
for _ in range(K):
pr = int(data[idx]) - 1; idx += 1
pc = int(data[idx]) - 1; idx += 1
guards.append((pr, pc))
grid = []
for _ in range(N):
grid.append(data[idx])
idx += 1
# Directions: up, down, left, right, stay
DIRS = [(-1,0), (1,0), (0,-1), (0,1), (0,0)]
DIR_ORDER = {'up':0, 'down':1, 'left':2, 'right':3, 'stay':4}
def is_valid(r, c):
return 0 <= r < N and 0 <= c < M and grid[r][c] == '.'
def manhattan(r1, c1, r2, c2):
return abs(r1-r2) + abs(c1-c2)
def move_guard(gr, gc, tr, tc):
# Possible moves
candidates = []
for i, (dr, dc) in enumerate(DIRS):
nr, nc = gr + dr, gc + dc
if is_valid(nr, nc):
dist = manhattan(nr, nc, tr, tc)
candidates.append((dist, i, nr, nc))
if not candidates:
return gr, gc
candidates.sort(key=lambda x: (x[0], x[1]))
return candidates[0][2], candidates[0][3]
# BFS with state: (turn, player_r, player_c, guard_positions)
# But since K<=2 and N,M<=8, we can represent guard positions as tuple
# State: (turn, pr, pc, ((gr1,gc1), (gr2,gc2), ...))
initial_state = (1, Sr, Sc, tuple(guards))
queue = deque([initial_state])
visited = set()
visited.add((Sr, Sc, tuple(guards)))
while queue:
turn, pr, pc, guard_pos = queue.popleft()
# Player possible moves
player_moves = []
for dr, dc in DIRS:
nr, nc = pr + dr, pc + dc
if is_valid(nr, nc):
player_moves.append((nr, nc))
for npr, npc in player_moves:
# Capture check after player move
caught1 = any((npr, npc) == gpos for gpos in guard_pos)
if caught1:
continue
# Escape check
if (npr, npc) == (Gr, Gc):
print(turn)
return
# Guard moves
new_guards = []
for gr, gc in guard_pos:
ng_r, ng_c = move_guard(gr, gc, npr, npc)
new_guards.append((ng_r, ng_c))
new_guard_tuple = tuple(new_guards)
# Capture check after guard move
caught2 = any((npr, npc) == gpos for gpos in new_guard_tuple)
if caught2:
continue
# Check if this state has been visited
state_key = (npr, npc, new_guard_tuple)
if state_key in visited:
continue
visited.add(state_key)
queue.append((turn+1, npr, npc, new_guard_tuple))
print(-1)
if __name__ == "__main__":
main()
This editorial was generated by qwen3-coder-480b.
投稿日時:
最終更新: