結果
| 問題 |
No.3121 Prime Dance
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-04-06 16:38:36 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 744 ms / 2,000 ms |
| コード長 | 2,969 bytes |
| コンパイル時間 | 176 ms |
| コンパイル使用メモリ | 82,660 KB |
| 実行使用メモリ | 81,492 KB |
| 最終ジャッジ日時 | 2025-04-08 23:39:37 |
| 合計ジャッジ時間 | 10,340 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 23 |
ソースコード
from collections import deque
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
C = [list(input()) for i in range(H)]
if Sx < Gx:
Sx = H-1-Sx
Gx = H-1-Gx
C.reverse()
if Sy < Gy:
Sy = W-1-Sy
Gy = W-1-Gy
for i in C:
i.reverse()
IINF = 10**8
def tup2idx(x, y, f):
return (x*W+y)*2+f
def idx2tup(n):
f = n & 1
n >>= 1
y = n % W
x = n//W
return x, y, f
def move_ok(x, y):
if x < 0 or x >= H or y < 0 or y >= W:
return False
return C[x][y] != "#"
def lb(A, x):
ok = len(A)
ng = -1
while ok-ng > 1:
mid = (ok+ng)//2
if A[mid] >= x:
ok = mid
else:
ng = mid
return ok
MAX_P = 10**5
prime = [True]*(MAX_P)
prime[0] = False
prime[1] = False
for i in range(2, MAX_P):
if not prime[i]:
continue
for j in range(i*i, MAX_P, i):
prime[j] = False
pH, pW = [], []
for i in range(MAX_P):
if i+(Sx-Gx) < MAX_P and prime[i] and prime[i+(Sx-Gx)]:
pH.append(i)
if i+(Sy-Gy) < MAX_P and prime[i] and prime[i+(Sy-Gy)]:
pW.append(i)
ans = IINF
distmemo = [[] for _ in range(H*W)]
distmemo[0].append(tup2idx(Sx, Sy, 0))
for a in range(H*W):
base = 0
dist = [IINF]*(H*W*2)
bfs = deque()
while base < H*W or bfs:
c = IINF
if bfs:
i = bfs.popleft()
c = dist[i]
bfs.appendleft(i)
if base < c:
for i in distmemo[base]:
if dist[i] > base:
dist[i] = base
bfs.appendleft(i)
base += 1
continue
i = bfs.popleft()
x, y, f = idx2tup(i)
c = dist[i]
# B
x2, y2 = x-1, y
if move_ok(x2, y2) and dist[tup2idx(x2, y2, f)] > c:
i2 = tup2idx(x2, y2, f)
dist[i2] = c
bfs.appendleft(i2)
# C
x2, y2 = x, y+1
if move_ok(x2, y2) and dist[tup2idx(x2, y2, 1)] > c+1:
i2 = tup2idx(x2, y2, 1)
dist[i2] = c+1
bfs.append(i2)
# D
x2, y2 = x, y-1
if move_ok(x2, y2) and dist[tup2idx(x2, y2, 1)] > c:
i2 = tup2idx(x2, y2, 1)
dist[i2] = c
bfs.appendleft(i2)
if a > 0:
c = dist[tup2idx(Gx, Gy, 1)]
h = lb(pH, a)
w = lb(pW, c)
if h < len(pH) and w < len(pW) and pH[h]*2+(Sx-Gx)+pW[w]*2+(Sy-Gy) < ans:
ans = pH[h]*2+(Sx-Gx)+pW[w]*2+(Sy-Gy)
for i in distmemo:
i.clear()
for x in range(H):
for y in range(W):
for f in range(2):
x2, y2 = x+1, y
i = tup2idx(x, y, f)
i2 = tup2idx(x2, y2, f)
if move_ok(x2, y2) and dist[i] < H*W:
distmemo[dist[i]].append(i2)
if ans == IINF:
print(-1)
else:
print(ans)