D - アイスリンクの脱出 / Escape from the Ice Rink 解説 by admin
Gemini 3.0 FlashOverview
On an \(H \times W\) grid-shaped ice rink, under a special movement rule where you cannot stop until you hit an obstacle (pillar) or a wall, find the minimum number of moves to get from the start position \((1, 1)\) to the goal position \((H, W)\).
Analysis
This problem can be viewed as a shortest path problem where each cell is treated as a “state (node)” and each move is treated as an “edge.”
1. Choosing a Shortest Path Algorithm
The cost of one move (from when you start sliding until you stop) is always \(1\), regardless of the distance traveled. For finding shortest paths in a graph where all edge weights are equal, Breadth-First Search (BFS) is optimal.
2. Simulating Movement
Unlike a typical maze search, instead of “moving to an adjacent cell,” you “keep moving until you hit an obstacle or a wall.” When moving from a cell \((r, c)\) in a specific direction (up, down, left, or right), coordinates are updated as long as the following conditions are met: - The next cell is within the rink boundaries (\(1 \le r \le H, 1 \le c \le W\)). - The next cell does not contain a pillar.
The cell just before these conditions are violated becomes the stopping position for that move.
3. Optimizing the Search
There is no point in reaching a previously visited cell with a greater number of moves. Therefore, we prepare a two-dimensional array dist[H][W] to record the minimum number of moves to each cell, and only explore unvisited cells.
Algorithm
- Preparation:
- Record pillar positions in a two-dimensional array (or set) for quick lookup.
- Initialize a two-dimensional array
distthat holds the minimum number of moves to each cell with \(-1\) (unvisited). - Prepare a queue (
deque), add the start position \((1, 1)\), and setdist[1][1] = 0.
- Executing BFS:
- Dequeue the current coordinates \((r, c)\).
- If \((r, c)\) is the goal \((H, W)\), output
dist[r][c]and terminate. - For each of the 4 directions (up, down, left, right):
- Simulate sliding one cell at a time from the current position in that direction until hitting a wall or pillar.
- Let \((nr, nc)\) be the coordinates of the cell where you stop.
- If
dist[nr][nc]is \(-1\), updatedist[nr][nc] = dist[r][c] + 1and add \((nr, nc)\) to the queue.
- Termination:
- If the queue becomes empty without reaching the goal, output
-1.
- If the queue becomes empty without reaching the goal, output
Complexity
- Time Complexity: \(O(HW \cdot \max(H, W))\)
- The number of states is the total number of cells \(O(HW)\).
- Simulating sliding in 4 directions from each state takes at most \(O(\max(H, W))\).
- Under the given constraints (\(H, W \le 100\)), this amounts to at most about \(100 \times 100 \times 100 = 1,000,000\) operations, which comfortably fits within the time limit.
- Space Complexity: \(O(HW)\)
- \(O(HW)\) memory is used to store the grid state (presence of pillars) and the distance to each cell.
Implementation Tips
Pillar Detection: By storing pillar positions in a boolean two-dimensional array
is_obstacle[r][c], collision detection during movement can be done in \(O(1)\).Sliding Logic: Using a
whileloop that checks “can we move to the next cell?”, advancing if possible and breaking out of the loop otherwise to set the current position as the stopping position, leads to a clean implementation.Fast I/O: In Python, when the amount of data is large, reading all input at once using
sys.stdin.read().split()improves execution speed.Source Code
import sys
from collections import deque
def solve():
# Read all input from standard input at once and split by whitespace
# This is generally faster for competitive programming in Python.
input_data = sys.stdin.read().split()
if not input_data:
return
# Parse the dimensions of the rink H, W and the number of pillars N
H = int(input_data[0])
W = int(input_data[1])
N = int(input_data[2])
# Create a 2D grid to store the positions of the pillars
# Using 1-based indexing (H+1 x W+1) to match the problem's coordinates
is_obstacle = [[False] * (W + 1) for _ in range(H + 1)]
for i in range(N):
r = int(input_data[3 + 2 * i])
c = int(input_data[3 + 2 * i + 1])
# Mark the pillar location
if 1 <= r <= H and 1 <= c <= W:
is_obstacle[r][c] = True
# dist[r][c] will store the minimum number of moves to reach square (r, c)
# Initialize with -1 to represent that the square has not been visited yet
dist = [[-1] * (W + 1) for _ in range(H + 1)]
# Initialize the BFS queue with the starting position (1, 1)
# Takahashi starts at (1, 1) with 0 moves
queue = deque([(1, 1)])
dist[1][1] = 0
# Standard BFS to find the shortest path in an unweighted graph
while queue:
r, c = queue.popleft()
# If the current position is the goal (H, W), we've found the minimum moves
if r == H and c == W:
print(dist[r][c])
return
# Takahashi can slide in four directions: Up, Down, Left, Right
for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
# Start sliding from the current position (r, c)
nr, nc = r, c
# Continue sliding in the chosen direction (dr, dc)
while True:
tr, tc = nr + dr, nc + dc
# Check if the next square is within the rink boundaries
# and if it is not blocked by a pillar
if 1 <= tr <= H and 1 <= tc <= W and not is_obstacle[tr][tc]:
# The square is accessible, so update the current position and continue
nr, nc = tr, tc
else:
# Takahashi stops if he hits the rink wall or the square before a pillar
break
# If the stopping square (nr, nc) has not been visited before,
# record the distance and add it to the BFS queue
if dist[nr][nc] == -1:
dist[nr][nc] = dist[r][c] + 1
queue.append((nr, nc))
# If the BFS finishes without reaching the goal (H, W), output -1
print("-1")
if __name__ == '__main__':
solve()
This editorial was generated by gemini-3-flash-preview.
投稿日時:
最終更新: