白駿2146号造橋
31086 ワード
白駿2146号造橋
問題のショートカット
トラブルシューティング
💣 bfsを用いた最小距離完全ナビゲーションの方法
この問題は、各領域から別の領域までの最短距離を求めることです.
この問題を解決するには、各領域が互いに独立している必要があります.
import sys
from collections import deque
def splitGround():
numbering = 2
for i in range(N):
for j in range(N):
if board[i][j] != 1:
continue
deq = deque()
deq.append([i, j])
board[i][j] = numbering
while deq:
r, c = deq.popleft()
for v in range(4):
newRow = r + dy[v]
newColumn = c + dx[v]
if newRow < 0 or newRow >= N or newColumn < 0 or newColumn >= N:
continue
if board[newRow][newColumn] == 1:
board[newRow][newColumn] = numbering
deq.append([newRow, newColumn])
numbering += 1
return numbering
def calculateMinDistance(countGround):
minDistance = 100001
distDictionary = {count : [[0 for i in range(N)] for v in range(N)] for count in range(2, countGround)}
for i in range(N):
for j in range(N):
if board[i][j] == 0:
continue
deq = deque()
deq.append([i, j])
number = board[i][j]
distBoard = distDictionary[number]
while deq:
r, c = deq.popleft()
dist = distBoard[r][c]
for v in range(4):
newRow = r + dy[v]
newColumn = c + dx[v]
if newRow < 0 or newRow >= N or newColumn < 0 or newColumn >= N:
continue
if board[newRow][newColumn] == 0:
if distBoard[newRow][newColumn] == 0:
distBoard[newRow][newColumn] = dist + 1
deq.append([newRow, newColumn])
if distBoard[newRow][newColumn] > dist + 1:
distBoard[newRow][newColumn] = dist + 1
deq.append([newRow, newColumn])
else:
if board[newRow][newColumn] != number:
minDistance = min(minDistance, dist)
break
return minDistance
N = int(sys.stdin.readline())
board = []
for i in range(N):
board.append(list(map(int, sys.stdin.readline().split())))
dy = [-1, 0, 1, 0]
dx = [0, 1, 0, -1]
countGround = splitGround()
print(calculateMinDistance(countGround))
結果は?
メモリオーバーフロー
スコアリング後、100 x 100サイズの配列を複数の異なる配列に分割すると、メモリが過剰に使用されるに違いありません.ほほほ
再帰関数を用いて解く
import sys
from collections import deque
def splitGround():
numbering = 2
for i in range(N):
for j in range(N):
if visited[i][j] != 1:
continue
deq = deque()
deq.append([i, j])
visited[i][j] = numbering
while deq:
r, c = deq.popleft()
for v in range(4):
newRow = r + dy[v]
newColumn = c + dx[v]
if newRow < 0 or newRow >= N or newColumn < 0 or newColumn >= N:
continue
if visited[newRow][newColumn] == 1:
visited[newRow][newColumn] = numbering
deq.append([newRow, newColumn])
numbering += 1
def calculateMinDistance(depth):
dist = 100001
for r in range(N):
for c in range(N):
if board[r][c] != depth:
continue
numbering = visited[r][c]
for v in range(4):
newRow = r + dy[v]
newColumn = c + dx[v]
if newRow < 0 or newRow >= N or newColumn < 0 or newColumn >= N:
continue
if board[newRow][newColumn] == 0:
board[newRow][newColumn] = depth + 1
visited[newRow][newColumn] = numbering
if board[newRow][newColumn] == depth and visited[newRow][newColumn] != numbering:
dist = min(dist, (depth-1) * 2)
if board[newRow][newColumn] == depth-1 and visited[newRow][newColumn] != numbering:
dist = min(dist, board[newRow][newColumn] + depth -2)
if dist != 1001:
return dist
return calculateMinDistance(depth + 1)
N = int(sys.stdin.readline())
board = []
visited = [[0 for _ in range(N)] for _ in range(N)]
for i in range(N):
board.append(list(map(int, sys.stdin.readline().split())))
for i in range(N):
for j in range(N):
if board[i][j] == 1:
visited[i][j] = 1
dy = [-1, 0, 1, 0]
dx = [0, 1, 0, -1]
splitGround()
print(calculateMinDistance(1))
メモリオーバーフローの解決方法を変更しました.bfsの使用と比較して,各領域で再帰関数を使用し,各重複再帰関数で領域を拡張する方法を採用した.
役に立つ反例
5
1 0 0 0 0
1 0 0 0 1
1 1 1 0 1
0 0 0 0 0
0 0 0 1 0
정답: 1
5
1 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 0 0 1
정답: 2
Reference
この問題について(白駿2146号造橋), 我々は、より多くの情報をここで見つけました https://velog.io/@yh20studio/백준-2146번-다리만들기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol