Official

D - 迷宮からの脱出 / Escape from the Labyrinth Editorial by admin Editorial for printing

DeepSeek V3

Overview

This problem involves Takahashi escaping from a maze containing security robots. Each turn, Takahashi and the robots move alternately, with capture checks and escape checks being performed. We need to find the minimum number of turns to escape with optimal play.

Analysis

Since the maze size is at most 8×8 and there are at most 2 security robots, state-space search is feasible. A state can be represented as (Takahashi’s position, all robots’ positions), and the number of states is at most \((8 \times 8) \times (8 \times 8)^K = 64 \times 64^K\). Even with K=2, this is only about 260,000 states. From each state, we only need to try 5 movement directions for Takahashi, so the minimum number of turns can be found using breadth-first search.

Algorithm

We use breadth-first search (BFS). A state is represented as (Takahashi’s row, Takahashi’s column, tuple of robot positions), and transitions from each state are generated as follows: 1. Try 5 options for Takahashi: move up, down, left, right, or stay 2. Skip if the destination is a wall 3. After moving, perform capture check 1: check if Takahashi is on the same cell as any robot 4. If at the exit, return the turn count as a successful escape 5. Move robots (according to the movement rules, moving closer to Takahashi), then perform capture check 2 6. If the new state has not been visited, add it to the queue

The robot movement rule is: among all possible movement candidates, select the one that minimizes the Manhattan distance to Takahashi. If distances are equal, prioritize in the order: up, down, left, right, stay.

Complexity

  • Time complexity: \(O((N \times M)^{K+1} \times 5)\)
  • Space complexity: \(O((N \times M)^{K+1})\)

Implementation Notes

  • Store robot positions as tuples for state identity comparison

  • In the robot movement function, enumerate all possible movement candidates and select based on distance calculation and priority order

  • Perform the two capture checks per turn in the correct order

  • Since grid coordinates are 1-indexed, convert to 0-indexed for access

    Source Code

import sys
from collections import deque

def main():
    data = sys.stdin.read().splitlines()
    if not data:
        print(-1)
        return
        
    first_line = data[0].split()
    N = int(first_line[0])
    M = int(first_line[1])
    K = int(first_line[2])
    S_r, S_c = map(int, data[1].split())
    G_r, G_c = map(int, data[2].split())
    robots = []
    idx = 3
    for i in range(K):
        r, c = map(int, data[idx].split())
        robots.append((r, c))
        idx += 1
        
    grid = []
    for i in range(N):
        grid.append(data[idx].strip())
        idx += 1
        
    dirs = [(-1,0), (1,0), (0,-1), (0,1), (0,0)]
    dir_names = ['上', '下', '左', '右', 'とどまる']
    
    def manhattan(r1, c1, r2, c2):
        return abs(r1 - r2) + abs(c1 - c2)
        
    def get_robot_move(pr, pc, h_r, h_c):
        candidates = []
        for dr, dc in dirs:
            nr = pr + dr
            nc = pc + dc
            if 1 <= nr <= N and 1 <= nc <= M and grid[nr-1][nc-1] == '.':
                candidates.append((nr, nc))
        best_dist = float('inf')
        best_move = None
        for cand in candidates:
            d = manhattan(cand[0], cand[1], h_r, h_c)
            if d < best_dist:
                best_dist = d
                best_move = cand
        return best_move
        
    def simulate_robots(robots_pos, h_r, h_c):
        new_robots = []
        for r_pos in robots_pos:
            new_pos = get_robot_move(r_pos[0], r_pos[1], h_r, h_c)
            new_robots.append(new_pos)
        return new_robots
        
    visited = set()
    q = deque()
    start_state = (S_r, S_c, tuple(robots))
    visited.add(start_state)
    q.append((0, S_r, S_c, robots))
    
    while q:
        turn, r, c, robots_state = q.popleft()
        if r == G_r and c == G_c:
            print(turn)
            return
            
        for dr, dc in dirs:
            nr = r + dr
            nc = c + dc
            if 1 <= nr <= N and 1 <= nc <= M and grid[nr-1][nc-1] == '.':
                new_robots_after_human = list(robots_state)
                captured1 = False
                for rob in new_robots_after_human:
                    if nr == rob[0] and nc == rob[1]:
                        captured1 = True
                        break
                if captured1:
                    continue
                    
                if nr == G_r and nc == G_c:
                    print(turn+1)
                    return
                    
                new_robots_after_move = simulate_robots(new_robots_after_human, nr, nc)
                captured2 = False
                for rob in new_robots_after_move:
                    if nr == rob[0] and nc == rob[1]:
                        captured2 = True
                        break
                if captured2:
                    continue
                    
                new_state = (nr, nc, tuple(new_robots_after_move))
                if new_state not in visited:
                    visited.add(new_state)
                    q.append((turn+1, nr, nc, new_robots_after_move))
                    
    print(-1)

if __name__ == "__main__":
    main()

This editorial was generated by deepseekv3.

posted:
last update: