Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- baeldung
- MAX
- 파이썬
- Til
- 3주차 회고
- 테이크스트라
- 누구나 자료구조와 알고리즘
- Map.of()
- requested
- 자유 프로젝트
- BOJ
- new File().toPath()
- 실패했지만성공했다
- 회고
- 채팅목록조회
- Spring
- 231103
- 오류
- Paths.get()
- 코드스쿼드max
- 코드스쿼드
- JazzMeet
- 백준
- 2023
- MapSqlParameterSource
- NamedParameterJdbcTemplate
- 22년도
- rotuter
- 재즈밋
- Python
Archives
- Today
- Total
어제보다 한걸음 더
BOJ 백준 4485번, 녹색 옷 입은 애가 젤다지? - Python 파이썬 본문
문제: https://www.acmicpc.net/problem/4485
4485번: 녹색 옷 입은 애가 젤다지?
젤다의 전설 게임에서 화폐의 단위는 루피(rupee)다. 그런데 간혹 '도둑루피'라 불리는 검정색 루피도 존재하는데, 이걸 획득하면 오히려 소지한 루피가 감소하게 된다! 젤다의 전설 시리즈의 주
www.acmicpc.net
요새 젤다의 전설 왕국의 눈물 재밌게 하고 있는데 이런 문제가 있어서 냉큼 풀어보게 되었다.ㅎㅎ
이 문제는 BFS나 다익스트라(테이크스트라)로 풀 수 있는데, 다익스트라에 익숙하지 않아서 처음에는 BFS와 섞어서 문제를 풀게 되었다.
# 첫번째 제출 코드
import sys
from collections import deque
input = sys.stdin.readline
INF = int(1e9)
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]
tc = 1
while True:
n = int(input().rstrip())
if n == 0: # 테스트 케이스 끝
break
graph = [list(map(int, input().rstrip().split())) for _ in range(n)]
distance = [[INF] * n for _ in range(n)]
def bfs(a, b):
q = deque()
q.append((a, b))
if a == 0 and b == 0: # 최초 한번만 돌게 해준다.
distance[0][0] = graph[0][0]
while q:
x, y = q.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or nx >= n or ny < 0 or ny >= n: # 범위 초과
continue
cost = graph[nx][ny] + distance[x][y]
if distance[nx][ny] > cost: # 최소 거리 갱신해야 한다면
distance[nx][ny] = cost
q.append((nx, ny))
for i in range(n):
for j in range(n):
if distance[i][j] == INF:
bfs(i, j)
print(f"Problem {tc}: {distance[n-1][n-1]}")
tc += 1
제출 결과
맞추긴 했지만 여러모로 아쉬운 풀이여서 시간을 줄이고, 다익스트라를 사용하도록 리팩토링 했다.
# 두번째 제출 코드
import sys
import heapq
input = sys.stdin.readline
INF = int(1e9)
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]
tc = 1
def dijkstra():
q = []
distance[0][0] = graph[0][0]
# 거리, x좌표, y좌표
heapq.heappush(q, (distance[0][0], 0, 0)) # 맨 앞의 값(거리)을 기준으로 정렬
while q:
dist, x, y = heapq.heappop(q)
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if nx < 0 or nx >= n or ny < 0 or ny >= n: # 범위 초과
continue
cost = dist + graph[nx][ny]
if distance[nx][ny] > cost: # 최소 거리 갱신해야 한다면
distance[nx][ny] = cost
heapq.heappush(q, (cost, nx, ny))
# 다익스트라 시작
while True:
n = int(input().rstrip())
if n == 0: # 테스트 케이스 끝
break
graph = [list(map(int, input().rstrip().split())) for _ in range(n)]
distance = [[INF] * n for _ in range(n)]
dijkstra()
print(f"Problem {tc}: {distance[n-1][n-1]}")
tc += 1
제출 결과
개선1 (시간 단축)
(0, 0)부터 (n-1, n-1)로 가는데 방문하지 못하는 노드는 없기 때문에(ex. 방해물) dijkstra() 함수를 한번만 호출해도 모든 노드(동굴 전체)를 돌게 된다.
따라서 방문하지 않은 노드를 탐색하는 2중 for문을 제거했다.
개선2 (deque 대신 priority queue 사용)
priority queue(heapq)를 이용하면 min-heap(거리)으로 정렬이 되기 때문에, 현재 노드로부터 다음 노드까지의 최단 거리가 먼저 pop()된다.
이후에 오는 거리는 모두 min-heap 보다 크기 때문에 최단 거리가 아니게 되어 24번째 줄에서 걸러진다.
'Computer Science > Algorithm' 카테고리의 다른 글
[책] 누구나 자료구조와 알고리즘 - 6장 긍정적인 시나리오 최적화 (3) | 2023.10.21 |
---|---|
BOJ 백준 14499번, 주사위 굴리기 - Python 파이썬 (2) | 2023.06.14 |
BOJ 백준 14235번, 크리스마스 선물 - Python 파이썬 (0) | 2023.04.05 |
BOJ 백준 13335번, 트럭 - Python 파이썬 (0) | 2023.04.05 |
BOJ 백준 1244번, 스위치 켜고 끄기 - Python 파이썬 (0) | 2023.03.28 |