728x90
시간제한 1초, 메모리제한 256MB
# 조건
- 젤다의 전설 게임에서 화폐의 단위는 루피(rupee)다.
- 그런데 간혹 '도둑루피'라 불리는 검정색 루피도 존재하는데, 이걸 획득하면 오히려 소지한 루피가 감소하게 된다!
- 젤다의 전설 시리즈의 주인공, 링크는 지금 도둑루피만 가득한 N x N 크기의 동굴의 제일 왼쪽 위에 있다.
- [0][0]번 칸이기도 하다.
- 왜 이런 곳에 들어왔냐고 묻는다면 밖에서 사람들이 자꾸 "젤다의 전설에 나오는 녹색 애가 젤다지?"라고 물어봤기 때문이다.
- 링크가 녹색 옷을 입은 주인공이고 젤다는 그냥 잡혀있는 공주인데, 게임 타이틀에 젤다가 나와있다고 자꾸 사람들이 이렇게 착각하니까 정신병에 걸릴 위기에 놓인 것이다.
- 하여튼 젤다...아니 링크는 이 동굴의 반대편 출구, 제일 오른쪽 아래 칸인 [N-1][N-1]까지 이동해야 한다.
- 동굴의 각 칸마다 도둑루피가 있는데, 이 칸을 지나면 해당 도둑루피의 크기만큼 소지금을 잃게 된다.
- 링크는 잃는 금액을 최소로 하여 동굴 건너편까지 이동해야 하며, 한 번에 상하좌우 인접한 곳으로 1칸씩 이동할 수 있다.
링크가 잃을 수밖에 없는 최소 금액은 얼마일까?
입력
- 입력은 여러 개의 테스트 케이스로 이루어져 있다.
- 각 테스트 케이스의 첫째 줄에는 동굴의 크기를 나타내는 정수 N이 주어진다. (2 ≤ N ≤ 125)
- N = 0인 입력이 주어지면 전체 입력이 종료된다.
- 이어서 N개의 줄에 걸쳐 동굴의 각 칸에 있는 도둑루피의 크기가 공백으로 구분되어 차례대로 주어진다.
- 도둑루피의 크기가 k면 이 칸을 지나면 k루피를 잃는다는 뜻이다.
- 여기서 주어지는 모든 정수는 0 이상 9 이하인 한 자리 수다.
# 접근 방법
시간초과
- bfs를이용하여 풀어준다.
- 상하좌우 인접한 칸을 deque에 넣어주며, visited 배열에 최소값을 기록해준다.
- 이 때, visited가 방문되지 않았거나, 아래와 같이 갱신해줄 수 있다면 방문 가능한 곳이다.
- 즉, 0,0은 5가 되며, 1,0은 8이되고, 0,1은 10이라고 가정하자.
- 이 때, 1,1은 13 < 18 이므로 13으로 갱신해준다.
from collections import deque
import sys
sys.stdin = open('input.txt')
di, dj = [1,-1,0,0], [0,0,1,-1]
def bfs(si, sj):
visited = [[0]*N for _ in range(N)]
q = deque()
q.append((si, sj))
visited[si][sj] = arr[0][0]
while q:
sti, stj = q.popleft()
for i in range(4):
ni, nj = di[i] + sti, dj[i] + stj
# 우선 범위 내라면
if 0<=ni<N and 0<=nj<N:
# 방문하지 않았다면
if visited[ni][nj] == 0:
q.append((ni, nj))
visited[ni][nj] = visited[sti][stj] + arr[ni][nj]
else:
if visited[ni][nj] > arr[ni][nj] + visited[sti][stj]:
q.append((ni, nj))
visited[ni][nj] = arr[ni][nj] + visited[sti][stj]
return visited[N-1][N-1]
cnt = 1
while True:
N = int(input())
if N == 0:
break
arr = [[*map(int, input().split())] for _ in range(N)]
result = bfs(0,0)
print(f'Problem {cnt} : {result}')
cnt += 1
정답 풀이
- 최단 거리를 구하는 것과 마찬가지이므로, 그래프로 풀어준다.
- 방문가능한 곳이라면 - 연결되어 있다면 - 가중치와 함께 heappush 해준다.
- heapq를 사용하여 다익스트라로 풀어준다면 시간이 O((v+e)log(v))가 되어 시간초과 없이 해결가능
from heapq import heappop, heappush
import sys
INF = 200000000
di, dj = [1,-1,0,0], [0,0,1,-1]
def bfs(graph):
dist = [[INF] * N for _ in range(N)]
dist[0][0] = graph[0][0]
q = []
heappush(q, (graph[0][0], 0,0))
while q:
val, si, sj = heappop(q)
if dist[si][sj] < val:
continue
for i in range(4):
ni = si + di[i]
nj = sj + dj[i]
if 0<= ni < N and 0<= nj < N:
if val + graph[ni][nj] < dist[ni][nj]:
dist[ni][nj] = val + graph[ni][nj]
heappush(q, (dist[ni][nj], ni, nj))
return dist[-1][-1]
cnt = 1
while True:
N = int(input())
if N == 0:
break
graph = []
for i in range(N):
graph.append([*map(int, input().split())])
result = bfs(graph)
print(f'Problem {cnt}: {result}')
cnt += 1
728x90
'ALGORITHM > 다익스트라, 벨만포드, 플로이드워셜' 카테고리의 다른 글
[프로그래머스 Lv3] 파이썬 - 등산 코스 정하기 (0) | 2023.07.29 |
---|---|
[백준 22955번] 파이썬 - 고양이 도도의 탈출기 (0) | 2023.07.17 |
[백준 17182번] 파이썬 - 우주 탐사선 (0) | 2023.01.12 |
[백준 14938번] 파이썬 - 서강 그라운드 (0) | 2022.12.29 |
[백준 1956번] 파이썬 - 운동 (1) | 2022.12.27 |