2024. 10. 6. 20:28ㆍ알고리즘
※ 사용언어 : 파이썬 ※
▼ 문제 링크 ▼
https://www.acmicpc.net/problem/1486
문제 접근
◇ 문제에서 요구하는 조건이 많은 편이다. 조건들을 간략하게 정리하면 다음과 같다.
1. 산의 지도(M)에 적힌 높이값은 "A-Z", "a-z" 로 구성. 해당 값을 숫자로 치환시, A-Z == 0-25 / a-z == 26-51
2. 상하좌우 이동하나, 높이 차이가 T 이하여야 함
3. 높이가 높은 곳 → 낮은 곳 => 이동시간 1초 / 높이가 낮은 곳 → 높은 곳 => 이동시간 (낮은 곳 - 높은 곳)^2
4. 해가 지기 전(D)에 시작 시점인 (0,0)으로 다시 돌아와야함.
◇ 모든 조건을 만족하면서 세준이가 갈 수 있는 최고 높이를 출력해야하는 문제이다.
문제 풀이 (With Python)
◇ 전체적인 코드의 흐름을 작성한다면 다음과 같습니다.
1. 위에서 서술한 조건 중 1~3번을 만족하는 좌표값들 다익스트라 알고리즘을 사용해 찾기
2. 찾은 좌표값 중 등산 시간이 D 미만인 좌표값을, heapque에 넣음 (이때 정렬 조건은 가장 높은 높이 부터.)
3. heapque에 들어간 좌표 값 중 조건 4번을 만족하는 값을 찾기
import heapq
import sys
N, M, T, D = map(int, sys.stdin.readline().split())
mountain = []
for _ in range(N):
mountain.append(list(sys.stdin.readline().rstrip()))
# 1번 조건
for a in range(N):
for b in range(M):
if mountain[a][b].isupper():
mountain[a][b] = ord(mountain[a][b]) - ord("A")
else:
mountain[a][b] = (ord(mountain[a][b]) - ord("a")) + 26
dx = [-1,1,0,0]
dy = [0,0,-1,1]
def Dijkstra(sx, sy):
time = [[int(1e9) for _ in range(M)] for _ in range(N)]
time[sx][sy] = 0
que = []
heapq.heappush(que, [0, sx, sy])
while que:
c_time, cx, cy = heapq.heappop(que)
if time[cx][cy] >= c_time:
c_height = mountain[cx][cy]
for i in range(4):
nx = cx + dx[i]
ny = cy + dy[i]
if 0 <= nx < N and 0 <= ny < M:
n_height = mountain[nx][ny]
# 2번 조건
if abs(c_height - n_height) <= T:
# 3번 조건
if c_height >= n_height:
n_time = c_time + 1
else:
n_time = c_time + (c_height - n_height) ** 2
if time[nx][ny] > n_time:
time[nx][ny] = n_time
heapq.heappush(que, [n_time, nx, ny])
return time
# 조건을 만족하는 좌표값들 찾기
check_time = Dijkstra(0, 0)
candi = []
for i in range(N):
for j in range(M):
if check_time[i][j] < D:
# 파이썬은 최소 heap만 제공해서 -1을 곱해야 최대 힙을 만들 수 있음
m_height = -1 * mountain[i][j]
heapq.heappush(candi, [m_height, i, j])
# 후보 좌표들 중 4번 조건을 만족하는 좌표 찾기
while candi:
pt, px, py = heapq.heappop(candi)
possible_time = Dijkstra(px, py)
# check_time: 0,0 -> px,py
# possible_time: px,py -> 0,0
if check_time[px][py] + possible_time[0][0] <= D:
print(mountain[px][py])
break
◇ 높이 계산을 편히 하기 위해, 본격적인 탐색에 들어가기에 앞서 알파벳 값을 조건에 맞는 숫자값으로 치환 (이 때, 아스키 코드상 대문자 Z 다음 바로 소문자 a가 시작하지 않기 때문에 대소문자를 구분하여 값을 매핑해줌)
◇ Dijkstra 함수 안의 time 배열을 선언하여 각 좌표에 도달할 수 있는 여러 시간대 중 최소값을 저장해줍니다.
◇ Dijkstra 함수 안의 while문에서 상하좌우로 움직이기 전, 해당 좌표값의 시간값이 time 배열에 저장된 것 보다 작거나 같은 경우만 순회합니다. (time 배열이 DFS와 DFS에서 사용되는 visited배열 역할을 담당)
'알고리즘' 카테고리의 다른 글
[프로그래머스] 미로 탈출 명령어 (2) | 2024.11.12 |
---|---|
[프로그래머스] 이모티콘 할인행사 파이썬 풀이 (0) | 2024.10.08 |
[프로그래머스] 리코쳇 로봇 파이썬 풀이 (0) | 2024.09.22 |
[백준] 보석 도둑 파이썬 풀이 (0) | 2024.01.31 |
[프로그래머스] 호텔 방 배정 (0) | 2023.09.10 |