https://www.acmicpc.net/problem/4485
문제가 웃겨서 홀린듯이.. 들어왔다.
젤다 .. 말고 링크가 동굴을 지나치면서 최소한의 금액만 잃도록 하는 문제다.
똑같은 다익스트라 문제인데, 방문 체크를 해주는 게 어려웠다.
동굴의 각 칸에 있는 도둑 루피의 크기가 공백으로 구분되어 있다.
한 줄씩 입력 받으면서 공백을 제거하고,
enumerate
로 인덱스와 값을 나누어서 cave[i][j]
에 도둑 루피 값을 넣어주었다.
for i in range(동굴 크기):
row = (input().rstrip()).replace(' ','')
for j,char in enumerate(row):
cave[i][j]=int(char)
thief
리스트엔, 각 위치에 따라 가장 적게 잃을 수 있는 루피 값을 비교해가면서 넣어줄 것이다.
deque로 만들어준 q
를 이용해 모든 위치를 방문 체크를 해나가면서 비교를 해줄 것이다.
q = deque()
q.append((0,0))
theif[0][0] = cave[0][0]
q
가 비어있지 않으면 계속 반복해준다.
while q:
i, j = q.popleft()
visited[0][0]=True
for k in range(4):
nx = i + dx[k]
ny = j + dy[k]
if 0 <= nx < n and 0 <= ny < n:
#현재 위치의 상하좌우 중 방문 안한 곳이 있으면 이동한다.
if not visited[nx][ny]:
# 만약 theif[이동할 좌표] 값이
# theif[현재 좌표] 값 + 도둑루피[이동할 좌표]의 합보다 크면
# 더 작은 값으로 갱신해준다.
# 그리고 q에 이동할 좌표를 넣어준다.
if theif[nx][ny] > theif[i][j] + cave[nx][ny]:
theif[nx][ny] = theif[i][j] + cave[nx][ny]
q.append((nx,ny))
Q. 왜 ( i, j )에 대해서 방문체크를 안해주지?
A. ( i, j )에 대해서 방문체크를 해버리면 한번 간 곳은 두번 다시 방문할 수 없다.
그러면 최소한의 루피를 잃는 길로 가지 않고, 출구쪽으로만 이동을 하면서, 비교를 하고 이동하게 된다.5 3 7 2 0 1 2 8 0 9 1 1 2 1 8 1 9 8 9 2 0 3 6 5 1 5
위와 같이 입력이 주어질 때, ( i, j )에 대해서 방문 체크를 한다면 theif의 값은 다음과 같다.
# 오답 [3, 10, 12, 12, 13] [5, 13, 12, 21, 14] [6, 8, 9, 17, 15] [15, 16, 18, 19, 15] [18, 22, 23, 20, 20]
# 정답 [3, 10, 11, 11, 12] [5, 13, 9, 18, 13] [6, 8, 9, 17, 14] [15, 16, 18, 16, 14] [18, 22, 22, 17, 19]
import sys
from collections import deque
input = sys.stdin.readline
cnt = 0
while(1):
#동굴 크기 n
n = int(input().rstrip())
cnt += 1
if n == 0 :
break
dx = [-1,1,0,0]
dy = [0,0,-1,1]
cave = [[0 for _ in range(n)] for _ in range(n)]
theif = [[99999 for _ in range(n)] for _ in range(n)]
visited = [[False for _ in range(n)] for _ in range(n)]
for i in range(n):
row = (input().rstrip()).replace(' ','')
for j,char in enumerate(row):
if char != " ":
cave[i][j]=int(char)
q = deque()
q.append((0,0))
theif[0][0] = cave[0][0]
while q:
i, j = q.popleft()
visited[0][0]=True
for k in range(4):
nx = i + dx[k]
ny = j + dy[k]
if 0 <= nx < n and 0 <= ny < n:
if not visited[nx][ny]:
if theif[nx][ny] > theif[i][j] + cave[nx][ny]:
theif[nx][ny] = theif[i][j] + cave[nx][ny]
q.append((nx,ny))
print("Problem {0}: {1}".format(cnt,theif[n-1][n-1]))
안녕하세요, 좋은 풀이 잘 보았습니다 :)
다름이 아니라 백준 문제 제목 부분에 "알고리즘 분류" 블록이 보이는데! 백준을 한참을 찾아봐도 관련 기능을 못 찾아갖고 혹시 어떻게 알고리즘 분류를 보이게 하셨는지 물어봐도 될까요?
알고리즘 공부하는데 유용하게 쓰려고 합니다..! 댓글 기다릴게요 :)