이 문제는 각 구역에서 다른 구역으로 가는 최단 거리를 구하는 것입니다.
해결하기 위해서는 각 구역끼리 서로 구분할 수 있어야합니다.
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))
처음에는 다음과 같은 흐름으로 문제를 풀었습니다. 그런데 각 구역별로 distance의 값들을 다르게 저장하고 있어야 하므로 distdictionary를 지정하고 구역별로 distBoard 배열을 구별해서 저장하는 방식을 사용했습니다.
결과는..?
메모리초과
채점을 하고 나서는 당연하게 느껴지는 것이 100X100 크기의 배열을 여러개 구별해서 사용하다보면 메모리 초과가 나는 것이 당연합니다.. ㅎㅎ
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