-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
69 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
--- | ||
title: 프로그래머스 - 택배 배달과 수거하기(python) | ||
createdTime: 2023-10-02 | ||
tags: | ||
- 프로그래머스 | ||
- 레벨2 | ||
- python | ||
- priority queue | ||
description: 프로그래머스 택배 배달과 수거하기 문제 풀이 | ||
--- | ||
|
||
## 택배 배달과 수거하기 | ||
|
||
당신은 일렬로 나열된 `n`개의 집에 택배를 배달하려 합니다. 배달할 물건은 모두 크기가 같은 재활용 택배 상자에 담아 배달하며, 배달을 다니면서 빈 재활용 택배 상자들을 수거하려 합니다. | ||
|
||
배달할 택배들은 모두 재활용 택배 상자에 담겨서 물류창고에 보관되어 있고, `i`번째 집은 물류창고에서 거리 `i`만큼 떨어져 있습니다. 또한 `i`번째 집은 `j`번째 집과 거리 `j - i` 만큼 떨어져 있습니다. (1 ≤ | ||
|
||
`i` ≤ `j` ≤ `n`) | ||
|
||
트럭에는 재활용 택배 상자를 최대 `cap`개 실을 수 있습니다. 트럭은 배달할 재활용 택배 상자들을 실어 물류창고에서 출발해 각 집에 배달하면서, 빈 재활용 택배 상자들을 수거해 물류창고에 내립니다. 각 집마다 배달할 재활용 택배 상자의 개수와 수거할 빈 재활용 택배 상자의 개수를 알고 있을 때, 트럭 하나로 모든 배달과 수거를 마치고 물류창고까지 돌아올 수 있는 최소 이동 거리를 구하려 합니다. | ||
|
||
**각 집에 배달 및 수거할 때, 원하는 개수만큼 택배를 배달 및 수거할 수 있습니다.** | ||
|
||
### 링크 | ||
|
||
[](https://school.programmers.co.kr/learn/courses/30/lessons/150369) | ||
|
||
**[ 문제에 대한 이해 ]** | ||
|
||
1. 일열로 나열된 n개의 집에 택배를 배달한다. | ||
2. 트럭에 실을 수 있는 택배상자의 개수는 최대 cap개이고, 각 집에 배달함과 동시에 빈 상자를 수거할 수 있다. | ||
3. 모든 배달과 수거를 마치고 물류창고까지 돌아올 수 있는 **최소** 거리를 구한다. | ||
|
||
|
||
### 어떤 칸에서부터 시작해야 할까? | ||
|
||
모르면 일단 아무 지점에서 사이클을 만들어보자. → 모든 지점에서 완전 탐색을 해보자. | ||
|
||
- 참고로, 사이클 특성 상 가장 첫 번째 위치에서만 탐색을 하더라도 모든 사이클의 파악이 가능하다. 모든 지점, 모든 방향에 대해 방문할 수 있다. | ||
- 동일한 사이클의 기준 | ||
- y, x 좌표에서 d 방향으로 이동한 이력이 있다면, 이미 사이클이 만들어졌다는 뜻이므로 더 이상 탐색할 필요가 없다. | ||
- 해당 지점에서 SLR에 따른 방향으로 이동할 경우 뒤 이동 경로는 동일하기 때문이다. | ||
|
||
## 접근 방법 | ||
|
||
### 어떤 방식으로 풀 수 있는가 | ||
|
||
우선 문제의 조건에서 총 배열의 길이가 10만까지 주어질 수 있다고 했으므로, 완전 탐색으로 해결은 불가능하다. 몇 번의 순회과정을 거쳐야 하는지도 알 수 없으며 그 과정에서 걸리는 시간 또한 예측이 불가능하기 때문이다. | ||
|
||
> 그리디 방식으로 최적의 해를 구할 수 있는지 확인한다. | ||
> | ||
우선 문제의 접근 방식을 따른다. 문제에서는 택배를 수거할 때 물류센터에서부터 가장 먼 곳의 택배부터 배달을 시작했다(최대로 실을 수 있을 때까지의 인덱스에서부터 시작한다). 그렇기 때문에 뒤에서 부터 순회하면서 채울 수 있는 최대의 개수만큼 채우고, 빈 박스 역시 마찬가지의 방법으로 수거하면서 물류센터로 돌아가면 된다. | ||
|
||
### 우선순위 큐로 접근하기 | ||
|
||
배열을 뒤에서부터 순회하면서 2번 순회하여 문제를 해결할 수 있을 수도 있지만, 이번 해결 방식에서는 우선순위 큐를 이용하였다. | ||
|
||
1. 우선순위 큐를 이용하여 가장 높은 인덱스부터 꺼내서 확인 | ||
2. distance의 최댓값을 저장하기 | ||
3. current_amount의 양 + 현재 인덱스의 값이 cap보다 작거나 같다면 값을 더하기 | ||
1. 그렇지 않다면 순회를 멈추고 총 cap에서 뺀 값을 다시 우선순위 큐에 집어넣기 | ||
4. 로직을 수거 시에도 적용하고, 저장한 최댓값에 * 2를 해서 total에 더하기 | ||
5. 큐에 모든 요소가 없을 때까지 반복하기 | ||
|
||
|
||
## 통과 코드 | ||
|
||
<div data-gist="d805c18b1e628098fae2a5b46d393356"></div> |