일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 재귀
- DFS
- 파이썬 #알고리즘 #코딩테스트 #프로그래머스
- 코딩테스트
- react #리액트 #동빈나 #나동빈 #유튜브강의
- java #자바 #나동빈
- react #리액트 #동빈나
- dp
- java #자바 #동빈나
- 파이썬 #백준 #알고리즘 #코딩테스트
- BFS
- 프로그래머스 #파이썬 #코딩테스트 #알고리즘
- 백트랙킹
- 백준
- java #자바 #생활코딩
- 백준 #알고리즘 #파이썬 #코딩테스트
- css #웹 #생활코딩
- 투포인터
- 프로그래머스 #파이썬 #알고리즘 #코딩테스트
- 파이썬
- 자바 #java
- 프로그래머스
- 백준 #파이썬 #알고리즘 #코딩테스트
- PYTHON
- 다익스트라
- css #생활코딩 #웹
- 알고리즘
- Dijkstra
- java #자바
- 다이나믹프로그래밍
- Today
- Total
커리까지
[프로그래머스] 광물 캐기 파이썬 본문
문제 설명
마인은 곡괭이로 광산에서 광석을 캐려고 합니다. 마인은 다이아몬드 곡괭이, 철 곡괭이, 돌 곡괭이를 각각 0개에서 5개까지 가지고 있으며, 곡괭이로 광물을 캘 때는 피로도가 소모됩니다. 각 곡괭이로 광물을 캘 때의 피로도는 아래 표와 같습니다.
예를 들어, 철 곡괭이는 다이아몬드를 캘 때 피로도 5가 소모되며, 철과 돌을 캘때는 피로도가 1씩 소모됩니다. 각 곡괭이는 종류에 상관없이 광물 5개를 캔 후에는 더 이상 사용할 수 없습니다.
마인은 다음과 같은 규칙을 지키면서 최소한의 피로도로 광물을 캐려고 합니다.
- 사용할 수 있는 곡괭이중 아무거나 하나를 선택해 광물을 캡니다.
- 한 번 사용하기 시작한 곡괭이는 사용할 수 없을 때까지 사용합니다.
- 광물은 주어진 순서대로만 캘 수 있습니다.
- 광산에 있는 모든 광물을 캐거나, 더 사용할 곡괭이가 없을 때까지 광물을 캡니다.
즉, 곡괭이를 하나 선택해서 광물 5개를 연속으로 캐고, 다음 곡괭이를 선택해서 광물 5개를 연속으로 캐는 과정을 반복하며, 더 사용할 곡괭이가 없거나 광산에 있는 모든 광물을 캘 때까지 과정을 반복하면 됩니다.
마인이 갖고 있는 곡괭이의 개수를 나타내는 정수 배열 picks
와 광물들의 순서를 나타내는 문자열 배열 minerals
가 매개변수로 주어질 때, 마인이 작업을 끝내기까지 필요한 최소한의 피로도를 return 하는 solution 함수를 완성해주세요.
제한사항
picks
는 [dia, iron, stone]과 같은 구조로 이루어져 있습니다.
- 0 ≤ dia, iron, stone ≤ 5
- dia는 다이아몬드 곡괭이의 수를 의미합니다.
- iron은 철 곡괭이의 수를 의미합니다.
- stone은 돌 곡괭이의 수를 의미합니다.
- 곡괭이는 최소 1개 이상 가지고 있습니다.
5 ≤
minerals
의 길이 ≤ 50
minerals
는 다음 3개의 문자열로 이루어져 있으며 각각의 의미는 다음과 같습니다.- diamond : 다이아몬드
- iron : 철
- stone : 돌
입출력 예
picks | minerals | result |
---|---|---|
[1, 3, 2] | ["diamond", "diamond", "diamond", "iron", "iron", "diamond", "iron", "stone"] | 12 |
[0, 1, 1] | ["diamond", "diamond", "diamond", "diamond", "diamond", "iron", "iron", "iron", "iron", "iron", "diamond"] | 50 |
입출력 예 설명
입출력 예 #1
다이아몬드 곡괭이로 앞에 다섯 광물을 캐고 철 곡괭이로 남은 다이아몬드, 철, 돌을 1개씩 캐면 12(1 + 1 + 1 + 1+ 1 + 5 + 1 + 1)의 피로도로 캘 수 있으며 이때가 최소값입니다.
입출력 예 #2
철 곡괭이로 다이아몬드 5개를 캐고 돌 곡괭이고 철 5개를 캐면 50의 피로도로 캘 수 있으며, 이때가 최소값입니다.
제출 답안
- 생각한 방법은
heapq
를 사용하는 방법이었다. - 힙을 이용하면 최솟값이 맨 앞으로 오기 때문에 각각의 곡괭이로 같은 광물을 캤을 경우를 append해서 나아가는 것이다.
- 즉 다이아몬으로 다이아몬드를 캐는게 가장 효율적이기 때문에 그 경우를 찾아야 한다.
- 그러나 이건 매우 복잡하다.
- 그래서 곡괭이로 같은 광물을 캔 경우에서 나아간다고 한 것이다.
- 예제 1번에서
"diamond", "diamond", "diamond", "iron", "iron"
을dia, iron, stone
으로 캔 결과를heapq
에 담는다. - 그러면 최솟값인 경우가 그 다음으로 오고 그럼 그 최솟값이 만들어진 경우에 사용되고 남은 곡괭이들의 리스트가 있다.
- 이렇게 하나씩 해결해나가고 마지막에 곡괭이를 다쓰거나 광물을 다 캔 경우에 피로도를 반환하면 된다.
import heapq
def get_pick(picks, idx, minerals, answer):
result = []
plus = min(5, len(minerals) - idx)
if picks[0] != 0:
temp = picks[:]
temp[0] -= 1
result.append((answer + plus, temp, idx + 5))
if picks[1] != 0:
temp = picks[:]
temp[1] -= 1
dia_cnt = minerals[idx:idx+5].count('diamond')
result.append((answer + plus - dia_cnt + (dia_cnt * 5), temp, idx + 5))
if picks[2] != 0:
temp = picks[:]
temp[2] -= 1
dia_cnt = minerals[idx:idx+5].count('diamond')
iron_cnt = minerals[idx:idx+5].count('iron')
result.append((answer + plus - dia_cnt - iron_cnt + (dia_cnt * 25) + (iron_cnt * 5), temp, idx + 5))
return result
def solution(picks, minerals):
idx = 0
answer = 0
heap = get_pick(picks, idx, minerals, answer)
while heap:
_answer, pick, idx = heapq.heappop(heap)
if sum(pick) == 0 or len(minerals) <= idx:
return _answer
result = get_pick(pick, idx, minerals, _answer)
for i in result:
heapq.heappush(heap, i)
'알고리즘 > 풀이' 카테고리의 다른 글
[프로그래머스] 우박수열 정적분 파이썬 (0) | 2023.05.11 |
---|---|
[프로그래머스] 리코쳇 로봇 파이썬 (1) | 2023.05.10 |
[프로그래머스] 1차 프렌즈 4블록 파이썬 (0) | 2023.05.06 |
[프로그래머스] 쿼드압축 후 개수 세기 파이썬 (0) | 2023.05.04 |
[프로그래머스] 스킬트리 파이썬 (0) | 2023.05.02 |