728x90
https://www.acmicpc.net/problem/2589
2589번: 보물섬
첫째 줄에는 보물 지도의 세로의 크기와 가로의 크기가 빈칸을 사이에 두고 주어진다. 이어 L과 W로 표시된 보물 지도가 아래의 예와 같이 주어지며, 각 문자 사이에는 빈 칸이 없다. 보물 지도의
www.acmicpc.net
해당 문제는 메모리제이션 기법과 완전탐색, 너비우선탐색으로 문제를 해결 하였습니다.
A(x1,y1), B(x2,y2) : A,B 각각 육지일때 dp[x1][y1][x2][y2] = 최소거리
1. 2중 for문으로 육지일때 각각의 육지에 대한 거리를 계산하여 dp 테이블에 넣습니다.
2. 육지의 그룹이 2개 이므로, 해당 육지내에서만 이동할 수 있으므로 조합을 생성하여 조합중 거리의 최대값을 리턴하면 됩니다.
# 육지의 그룹을 분리한다( 너비우선 탐색 )
# 각각의 그룹으로부터 2개의 조합을 만들어 최단거리를 구한다. 그 최단 거리중 가장 큰 값을 return 하면 정답
from collections import deque
from itertools import combinations
N, M = map(int, input().split()) # 세로, 가로
move = [(0, 1), (0, -1), (1, 0), (-1, 0)]
graph = [list(input()) for _ in range(N)]
# 그룹별 좌표를 반환하는 함수
def getGroup():
groupList = []
visited = [[False] * M for _ in range(N)]
for i in range(N):
for j in range(M):
if graph[i][j] == 'L' and not visited[i][j]:
group = []
queue = deque()
queue.append((i, j))
visited[i][j] = True
group.append((i, j))
while queue:
y, x = queue.popleft()
for dy, dx in move:
ny, nx = y + dy, x + dx
if 0 <= ny < N and 0 <= nx < M and not visited[ny][nx] and graph[ny][nx] == 'L':
visited[ny][nx] = True
queue.append((ny, nx))
group.append((ny, nx))
groupList.append(group)
return groupList
# 미리 모든 정점 간 거리를 계산한 후 메모이제이션
distance = [[[[float('inf')] * M for _ in range(N)] for _ in range(M)] for _ in range(N)]
for i in range(N):
for j in range(M):
if graph[i][j] == 'L':
queue = deque()
queue.append((i, j, 0))
distance[i][j][i][j] = 0
while queue:
y, x, cost = queue.popleft()
for dy, dx in move:
ny, nx = y + dy, x + dx
if 0 <= ny < N and 0 <= nx < M and graph[ny][nx] == 'L' and distance[i][j][ny][nx] == float('inf'):
distance[i][j][ny][nx] = cost + 1
queue.append((ny, nx, cost + 1))
grouplist = getGroup()
maxvalue = 0
# 그룹 내의 노드 쌍에 대한 최단 거리 계산
for group in grouplist:
for a, b in combinations(group, 2):
maxvalue = max(maxvalue, distance[a[0]][a[1]][b[0]][b[1]])
print(maxvalue)
728x90
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 1038번 : 감소하는 수 (0) | 2023.08.17 |
---|---|
[백준] 17142번 : 연구소 3 (0) | 2023.08.16 |
[백준] 1068번 : 트리 (0) | 2023.08.08 |
[백준] 16638번 : 괄호 추가하기 2 (0) | 2023.08.07 |
[백준] 1285번 : 동전 뒤집기 (0) | 2023.08.07 |