일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- css #웹 #생활코딩
- 백트랙킹
- react #리액트 #동빈나 #나동빈 #유튜브강의
- PYTHON
- 프로그래머스 #파이썬 #알고리즘 #코딩테스트
- 파이썬
- DFS
- java #자바 #나동빈
- 파이썬 #백준 #알고리즘 #코딩테스트
- 자바 #java
- 알고리즘
- 다이나믹프로그래밍
- 투포인터
- 프로그래머스
- 백준 #파이썬 #알고리즘 #코딩테스트
- 다익스트라
- java #자바 #생활코딩
- 프로그래머스 #파이썬 #코딩테스트 #알고리즘
- BFS
- 백준
- react #리액트 #동빈나
- Dijkstra
- dp
- java #자바
- 파이썬 #알고리즘 #코딩테스트 #프로그래머스
- java #자바 #동빈나
- css #생활코딩 #웹
- 재귀
- 코딩테스트
- 백준 #알고리즘 #파이썬 #코딩테스트
- Today
- Total
커리까지
[프로그래머스] 등산코스 정하기 파이썬 본문
문제 설명
XX산은 n
개의 지점으로 이루어져 있습니다. 각 지점은 1부터 n
까지 번호가 붙어있으며, 출입구, 쉼터, 혹은 산봉우리입니다. 각 지점은 양방향 통행이 가능한 등산로로 연결되어 있으며, 서로 다른 지점을 이동할 때 이 등산로를 이용해야 합니다. 이때, 등산로별로 이동하는데 일정 시간이 소요됩니다.
등산코스는 방문할 지점 번호들을 순서대로 나열하여 표현할 수 있습니다.
예를 들어 1-2-3-2-1
으로 표현하는 등산코스는 1번지점에서 출발하여 2번, 3번, 2번, 1번 지점을 순서대로 방문한다는 뜻입니다.
등산코스를 따라 이동하는 중 쉼터 혹은 산봉우리를 방문할 때마다 휴식을 취할 수 있으며, 휴식 없이 이동해야 하는 시간 중 가장 긴 시간을 해당 등산코스의 intensity
라고 부르기로 합니다.
당신은 XX산의 출입구 중 한 곳에서 출발하여 산봉우리 중 한 곳만 방문한 뒤 다시 원래의 출입구로 돌아오는 등산코스를 정하려고 합니다. 다시 말해, 등산코스에서 출입구는 처음과 끝에 한 번씩, 산봉우리는 한 번만 포함되어야 합니다.
당신은 이러한 규칙을 지키면서 intensity
가 최소가 되도록 등산코스를 정하려고 합니다.
다음은 XX산의 지점과 등산로를 그림으로 표현한 예시입니다.
- 위 그림에서 원에 적힌 숫자는 지점의 번호를 나타내며, 1, 3번 지점에 출입구, 5번 지점에 산봉우리가 있습니다. 각 선분은 등산로를 나타내며, 각 선분에 적힌 수는 이동 시간을 나타냅니다. 예를 들어 1번 지점에서 2번 지점으로 이동할 때는 3시간이 소요됩니다.
위의 예시에서 1-2-5-4-3
과 같은 등산코스는 처음 출발한 원래의 출입구로 돌아오지 않기 때문에 잘못된 등산코스입니다. 또한 1-2-5-6-4-3-2-1
과 같은 등산코스는 코스의 처음과 끝 외에 3번 출입구를 방문하기 때문에 잘못된 등산코스입니다.
등산코스를 3-2-5-4-3
과 같이 정했을 때의 이동경로를 그림으로 나타내면 아래와 같습니다.
이때, 휴식 없이 이동해야 하는 시간 중 가장 긴 시간은 5시간입니다. 따라서 이 등산코스의 intensity
는 5입니다.
등산코스를 1-2-4-5-6-4-2-1
과 같이 정했을 때의 이동경로를 그림으로 나타내면 아래와 같습니다.
이때, 휴식 없이 이동해야 하는 시간 중 가장 긴 시간은 3시간입니다. 따라서 이 등산코스의 intensity
는 3이며, 이 보다 intensity
가 낮은 등산코스는 없습니다.
XX산의 지점 수 n
, 각 등산로의 정보를 담은 2차원 정수 배열 paths
, 출입구들의 번호가 담긴 정수 배열 gates
, 산봉우리들의 번호가 담긴 정수 배열 summits
가 매개변수로 주어집니다. 이때, intensity
가 최소가 되는 등산코스에 포함된 산봉우리 번호와 intensity
의 최솟값을 차례대로 정수 배열에 담아 return 하도록 solution 함수를 완성해주세요. intensity
가 최소가 되는 등산코스가 여러 개라면 그중 산봉우리의 번호가 가장 낮은 등산코스를 선택합니다.
제한사항
- 2 ≤
n
≤ 50,000 n
- 1 ≤paths
의 길이 ≤ 200,000paths
의 원소는[i, j, w]
형태입니다.i
번 지점과j
번 지점을 연결하는 등산로가 있다는 뜻입니다.w
는 두 지점 사이를 이동하는 데 걸리는 시간입니다.- 1 ≤
i
<j
≤n
- 1 ≤
w
≤ 10,000,000 - 서로 다른 두 지점을 직접 연결하는 등산로는 최대 1개입니다.
- 1 ≤
gates
의 길이 ≤n
- 1 ≤
gates
의 원소 ≤n
gates
의 원소는 해당 지점이 출입구임을 나타냅니다.
- 1 ≤
- 1 ≤
summits
의 길이 ≤n
- 1 ≤
summits
의 원소 ≤n
summits
의 원소는 해당 지점이 산봉우리임을 나타냅니다.
- 1 ≤
- 출입구이면서 동시에 산봉우리인 지점은 없습니다.
gates
와summits
에 등장하지 않은 지점은 모두 쉼터입니다.- 임의의 두 지점 사이에 이동 가능한 경로가 항상 존재합니다.
- return 하는 배열은
[산봉우리의 번호, intensity의 최솟값]
순서여야 합니다.
입출력 예
n | paths | gates | summits | result |
---|---|---|---|---|
6 | [[1, 2, 3], [2, 3, 5], [2, 4, 2], [2, 5, 4], [3, 4, 4], [4, 5, 3], [4, 6, 1], [5, 6, 1]] | [1, 3] | [5] | [5, 3] |
7 | [[1, 4, 4], [1, 6, 1], [1, 7, 3], [2, 5, 2], [3, 7, 4], [5, 6, 6]] | [1] | [2, 3, 4] | [3, 4] |
7 | [[1, 2, 5], [1, 4, 1], [2, 3, 1], [2, 6, 7], [4, 5, 1], [5, 6, 1], [6, 7, 1]] | [3, 7] | [1, 5] | [5, 1] |
5 | [[1, 3, 10], [1, 4, 20], [2, 3, 4], [2, 4, 6], [3, 5, 20], [4, 5, 6]] | [1, 2] | [5] | [5, 6] |
입출력 예 설명
입출력 예 #1
문제 예시와 같습니다. 등산코스의 intensity
가 최소가 되는 산봉우리 번호는 5, intensity
의 최솟값은 3이므로 [5, 3]
을 return 해야 합니다.
입출력 예 #2
XX산의 지점과 등산로를 그림으로 표현하면 아래와 같습니다.
가능한 intensity
의 최솟값은 4이며, intensity
가 4가 되는 등산코스는 1-4-1
과 1-7-3-7-1
이 있습니다. intensity
가 최소가 되는 등산코스가 여러 개이므로 둘 중 산봉우리의 번호가 낮은 1-7-3-7-1
을 선택합니다. 따라서 [3, 4]
를 return 해야 합니다.
입출력 예 #3
XX산의 지점과 등산로를 그림으로 표현하면 아래와 같습니다.
가능한 intensity
의 최솟값은 1이며, 그때의 등산코스는 7-6-5-6-7
입니다. 따라서 [5, 1]
를 return 해야 합니다.
7-6-5-4-1-4-5-6-7
과 같은 등산코스는 산봉우리를 여러 번 방문하기 때문에 잘못된 등산코스입니다.
입출력 예 #4
XX산의 지점과 등산로를 그림으로 표현하면 아래와 같습니다.
가능한 intensity
의 최솟값은 6, 그때의 등산코스는 2-4-5-4-2
입니다. 따라서 [5, 6]
을 return 해야 합니다.
참고 답안
- https://www.youtube.com/watch?v=xLG6e4ov9dY
- 위 영상에서 자세한 해설을 볼 수 있다.
- 다익스트라를 기본만 알고 있던 나에게 어떻게 응용해야 하는지 알려주었다.
- 또한 반복문을 줄여서 시간을 단축하는 방법도 좋았다.
import heapq
def solution(n, paths, gates, summits):
gates, summits = set(gates), set(summits)
conn = [[] for _ in range(n+1)]
for i, j, w in paths:
if i not in summits and j not in gates:
conn[i].append((j, w))
if j not in summits and i not in gates:
conn[j].append((i, w))
pq = [(0, gate) for gate in gates]
MAX = 10000001
min_dis = [MAX for _ in range(n+1)]
while pq:
intensity, node = heapq.heappop(pq)
if min_dis[node] <= intensity:
continue
min_dis[node] = intensity
for nxt, nxt_w in conn[node]:
nxt_w = max(intensity, nxt_w)
if min_dis[nxt] <= nxt_w:
continue
heapq.heappush(pq, (nxt_w, nxt))
answer = [0, MAX]
for summit in summits:
if min_dis[summit] < answer[1]:
answer[0], answer[1] = summit, min_dis[summit]
elif min_dis[summit] == answer[1] and summit < answer[0]:
answer[0] = summit
return answer
'알고리즘 > 풀이' 카테고리의 다른 글
[프로그래머스] 야근 지수 파이썬 (0) | 2023.06.06 |
---|---|
[프로그래머스] 최고의 집합 파이썬 (0) | 2023.06.05 |
[프로그래머스] 과제 진행하기 파이썬 (0) | 2023.05.19 |
[프로그래머스] 이모티콘 할인행사 파이썬 (0) | 2023.05.18 |
[프로그래머스] 혼자서 하는 틱택토 파이썬 (0) | 2023.05.17 |