import heapq
def solution(food_times, k):
# 음식 시간의 총 합이 k와 같거나 작으면
# 다음으로 먹을 음식이 없는 것이므로 -1 리턴
if (sum(food_times) <= k) :
return -1
# 우선순위 큐
q = []
for i in range(len(food_times)) :
# (음식 시간, 음식 번호) 형태로 큐에 삽입
heapq.heappush(q, (food_times[i], i+1))
length = len(food_times) # 남은 음식 개수
sum_value = 0 # 한 음식을 다 먹기 위해 걸린 시간
prev = 0 # 이전에 음식을 먹는데 걸린 시간
# 남은 음식 개수 * (제일 작게 걸리는 음식 시간 - 이전에 먹은 시간) 이
# k - (지금까지 먹은 시간) 보다 작거나 같을 때 반복하기
# -> 한 음식을 다 먹을 수 있으면 반복문 실행
while (length * (q[0][0] - prev) <= (k - sum_value)):
# 시간이 가장 작게 걸리는 음식을 pop 하고, now에 저장
now = heapq.heappop(q)[0]
# [(한 음식을 먹는데 걸리는 총 시간) - (이전까지 먹은 시간)] * 음식 개수
sum_value += (now - prev) * length
length -= 1 # 음식 개수 하나 빼기
prev = now
# 남은 음식 중에서 몇 번째 음식인지 확인
result = sorted(q, key=lambda x: x[1]) # 번호 순대로 오름차순 정렬
return result[(k - sum_value) % length][1]
최소 힙을 이용해서, 먹는데 가장 시간이 작게 걸리는 음식부터 제거해 나가는 방식을 사용한다.
예로 food_times 가 3초(1번), 1초(2번), 2초(3번) , k = 5초 일 때를 생각해보자.
먼저 가장 시간이 작게 걸리는 2번째 음식을 제거한다고 생각해보자.
2번을 다 먹는데에 1초가 걸린다. 즉, 2번을 다 먹기 위해 1초 * 3개(음식개수, 음식은 순서대로 먹어야 하므로) -> 3초 가 걸린다.
다음으로 작게 걸리는 3번 음식을 먹는다고 하자. 3번을 다 먹는데에 2초가 걸리지만 아까 먹은 1초를 빼야한다.
즉, 3번을 다 먹기 위해 (2-1)초 * 2개(음식개수) -> 2초 가 걸린다.
다음으로 1번 음식을 먹어야 하는데, 지금까지 음식을 먹는데 걸린 시간은 5초이고, k 도 5초이다.
더 이상 k초까지 음식을 먹을 수 없다.
따라서 (k - 지금까지 먹은 시간) % 남은 음식 개수 로 다음에 먹을 음식을 구할 수 있다.
볼 때마다 또 까먹고 또 까먹게 되는 문제..ㅎㅎㅎㅎ 계속 보고 머리에 넣자...
'알고리즘 > 그리디' 카테고리의 다른 글
[Python] 백준 1783: 병든 나이트 (0) | 2021.09.23 |
---|---|
[Python] 백준 10610: 30 (0) | 2021.09.14 |
[Python] 백준 2875: 대회 or 인턴 (0) | 2021.09.08 |
[Python] 백준 11047: 동전 0 (0) | 2021.09.07 |
[K 대회 기출] 만들 수 없는 금액 (0) | 2021.09.07 |
댓글