C - 島巡りの冒険 / Island Hopping Adventure 解説 by admin
Claude 4.6 Opus (Thinking)Overview
This is a shortest path problem where \(N\) islands are placed on a two-dimensional plane, and we need to find the minimum number of moves to travel from island \(S\) to island \(T\) by repeatedly moving to islands within Euclidean distance \(D\).
Analysis
Key Observations
- Whether an “edge” exists between two islands is determined by whether the Euclidean distance is at most \(D\). In other words, this can be reduced to a shortest path problem on a graph where islands are nodes and pairs within distance \(D\) are edges.
- Since each edge has equal weight (cost) of “one move,” this is a shortest path problem on an unweighted graph. The shortest path on an unweighted graph can be found using BFS (Breadth-First Search).
Naive Approach and Its Feasibility
- Precomputing distances for all pairs and building an adjacency list requires \(O(N^2)\) preprocessing. Since \(N \leq 1500\), we have \(N^2 = 2{,}250{,}000\), which is fast enough to handle.
- If \(N\) were \(10^5\) or more, \(O(N^2)\) would be too slow, but for this problem with \(N \leq 1500\), there is no issue.
Optimizing Euclidean Distance Comparison
- The check \(\sqrt{(X_u - X_v)^2 + (Y_u - Y_v)^2} \leq D\) can be done by squaring both sides to get \((X_u - X_v)^2 + (Y_u - Y_v)^2 \leq D^2\), which avoids computing square roots and allows exact comparison using only integer arithmetic.
Algorithm
- Read the input and store the coordinates of each island.
- Precompute \(D^2\).
- Perform BFS starting from island \(S\).
- Each time island \(u\) is dequeued, for all islands \(v\) (\(0 \leq v < N\)):
- If \(v\) has not been visited yet (
dist[v] == -1) and the distance condition \((X_u - X_v)^2 + (Y_u - Y_v)^2 \leq D^2\) is satisfied, mark \(v\) as visited and add it to the queue.
- If \(v\) has not been visited yet (
- If island \(T\) is reached, output the number of moves at that point.
- Each time island \(u\) is dequeued, for all islands \(v\) (\(0 \leq v < N\)):
- If BFS finishes without reaching island \(T\), output \(-1\).
Concrete Example
For instance, if three islands are at \((0,0)\), \((3,0)\), \((7,0)\) with \(D=4\), \(S=1\), \(T=3\): - Island 1 → Island 2: distance \(3 \leq 4\), so movement is possible - Island 2 → Island 3: distance \(4 \leq 4\), so movement is possible - Island 1 → Island 3: distance \(7 > 4\), so direct movement is not possible
Therefore, we can reach island 3 via island 1 → island 2 → island 3 in 2 moves, and the answer is \(2\).
Complexity
- Time Complexity: \(O(N^2)\)
- At each step of BFS, for each node dequeued, we scan all \(N\) nodes. Since each node enters the queue at most once, the total is \(O(N \times N) = O(N^2)\).
- Space Complexity: \(O(N)\)
- The coordinate array, distance array, and BFS queue each use \(O(N)\). Since we do not explicitly build an adjacency list, \(O(N^2)\) memory is not needed.
Implementation Notes
Do not pre-build an adjacency list: By performing distance checks on the fly during BFS exploration, we save memory while keeping the implementation simple.
Compare using squared distances: To completely avoid errors from floating-point arithmetic, compare \(D^2\) with the squared distance using integers. Since coordinates and \(D\) can be up to \(10^9\), squaring them yields values up to approximately \(4 \times 10^{18}\), but Python handles arbitrary-precision integers, so there is no concern about overflow.
Early termination: By immediately outputting the result and terminating as soon as island \(T\) is reached, we skip unnecessary exploration.
Source Code
import sys
from collections import deque
def main():
input_data = sys.stdin.buffer.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
D = int(input_data[idx]); idx += 1
S = int(input_data[idx]) - 1; idx += 1
T = int(input_data[idx]) - 1; idx += 1
X = [0] * N
Y = [0] * N
for i in range(N):
X[i] = int(input_data[idx]); idx += 1
Y[i] = int(input_data[idx]); idx += 1
D2 = D * D
# BFS with distance check on the fly (N<=1500, so O(N^2) is fine)
dist = [-1] * N
dist[S] = 0
queue = deque([S])
while queue:
u = queue.popleft()
if u == T:
print(dist[T])
return
for v in range(N):
if dist[v] == -1:
dx = X[u] - X[v]
dy = Y[u] - Y[v]
if dx * dx + dy * dy <= D2:
dist[v] = dist[u] + 1
queue.append(v)
print(-1)
main()
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: