結果
| 問題 |
No.3121 Prime Dance
|
| ユーザー |
|
| 提出日時 | 2025-04-19 20:30:08 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,768 bytes |
| コンパイル時間 | 220 ms |
| コンパイル使用メモリ | 12,928 KB |
| 実行使用メモリ | 11,520 KB |
| 最終ジャッジ日時 | 2025-04-19 20:30:10 |
| 合計ジャッジ時間 | 2,315 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 WA * 6 |
ソースコード
from collections import deque
import sys
input = sys.stdin.readline
def sieve(n):
is_prime = [True]*(n+1)
if n >= 0: is_prime[0] = False
if n >= 1: is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
for j in range(i*i, n+1, i):
is_prime[j] = False
return is_prime
def find_shift(c0, d0, can_loop, is_prime, LIMIT):
# if no loop allowed, only x=0
if not can_loop:
return 0 if c0<=LIMIT and d0<=LIMIT and is_prime[c0] and is_prime[d0] else None
# otherwise scan x>=0
for x in range(LIMIT+1):
cc = c0 + x
dd = d0 + x
if cc <= LIMIT and dd <= LIMIT and is_prime[cc] and is_prime[dd]:
return x
return None
def try_variant(H, W, grid, Sx, Sy, Gx, Gy, DIRS, is_prime, LIMIT):
# BFS to get parent pointers and reachable-visited
visited = [[False]*W for _ in range(H)]
parent = {}
q = deque([(Sx, Sy)])
visited[Sx][Sy] = True
while q:
x, y = q.popleft()
for dx, dy in DIRS:
nx, ny = x + dx, y + dy
if 0 <= nx < H and 0 <= ny < W and not visited[nx][ny] and grid[nx][ny] != '#':
visited[nx][ny] = True
parent[(nx,ny)] = ((x,y), (dx,dy))
q.append((nx,ny))
# if G unreachable
if not visited[Gx][Gy]:
return float('inf')
# reconstruct one shortest path by following parents
path = []
cur = (Gx, Gy)
while cur != (Sx, Sy):
(px, py), move = parent[cur]
path.append(move)
cur = (px, py)
path.reverse()
# count base-path moves
A0 = sum(1 for dx,dy in path if dx == 1 and dy == 0)
B0 = sum(1 for dx,dy in path if dx == -1 and dy == 0)
C0 = sum(1 for dx,dy in path if dx == 0 and dy == 1)
D0 = sum(1 for dx,dy in path if dx == 0 and dy == -1)
base_len = len(path)
# check if vertical/horizontal loops can be inserted anywhere in the component
vert_ok = horz_ok = False
for x in range(H):
for y in range(W):
if visited[x][y]:
if x+1 < H and visited[x+1][y]:
vert_ok = True
if y+1 < W and visited[x][y+1]:
horz_ok = True
if vert_ok and horz_ok:
break
if vert_ok and horz_ok:
break
# find minimal x and y
x = find_shift(A0, B0, vert_ok, is_prime, LIMIT)
if x is None:
return float('inf')
y = find_shift(C0, D0, horz_ok, is_prime, LIMIT)
if y is None:
return float('inf')
# total = (A0+B0+C0+D0) + 2*(x+y) = base_len + 2*(x+y)
return base_len + 2*(x + y)
def solve():
H, W = map(int, input().split())
Sx, Sy = map(int, input().split())
Gx, Gy = map(int, input().split())
Sx -= 1; Sy -= 1; Gx -= 1; Gy -= 1
grid = [input().rstrip() for _ in range(H)]
# sieve far enough: worst base_len ≤ H*W, loops ≤ +2000
LIMIT = H*W + 2000
is_prime = sieve(LIMIT)
# three variants of neighbor order
ΔV, ΔH = Gx - Sx, Gy - Sy
DIRS1 = [(1,0), (-1,0), (0,1), (0,-1)] # down, up, right, left
DIRS2 = [(0,1), (0,-1), (1,0), (-1,0)] # right, left, down, up
# goal‐directed first
order3 = []
order3.append((1,0) if ΔV>0 else (-1,0))
order3.append((0,1) if ΔH>0 else (0,-1))
for d in [(1,0),(-1,0),(0,1),(0,-1)]:
if d not in order3:
order3.append(d)
DIRS3 = order3
ans = min(
try_variant(H,W,grid,Sx,Sy,Gx,Gy,DIRS1,is_prime,LIMIT),
try_variant(H,W,grid,Sx,Sy,Gx,Gy,DIRS2,is_prime,LIMIT),
try_variant(H,W,grid,Sx,Sy,Gx,Gy,DIRS3,is_prime,LIMIT),
)
print(ans if ans < float('inf') else -1)
if __name__ == "__main__":
solve()