준호는 요즘 디펜스 게임에 푹 빠져 있습니다. 디펜스 게임은 준호가 보유한 병사 n명으로 연속되는 적의 공격을 순서대로 막는 게임입니다. 디펜스 게임은 다음과 같은 규칙으로 진행됩니다.
준호는 무적권을 적절한 시기에 사용하여 최대한 많은 라운드를 진행하고 싶습니다.
준호가 처음 가지고 있는 병사의 수 n, 사용 가능한 무적권의 횟수 k, 매 라운드마다 공격해오는 적의 수가 순서대로 담긴 정수 배열 enemy가 매개변수로 주어집니다. 준호가 몇 라운드까지 막을 수 있는지 return 하도록 solution 함수를 완성해주세요.
문제를 쭉 읽어보면 알겠지만, 우리는 다음과 같은 생각을 할 수 있다.
- 여태까지 지나온 스테이지들 중에서, 적이 가장 많은 스테이지들에만 무적권을 사용하고 싶다.
- 무적권을 사용하면 병사의 수가 차감되지 않는다. (k만 차감)
여기에서 1번 아이디어가 되게 핵심인데, 즉, 우리는 지나온 스테이지들 중에서 최댓값만 한번에 쏙쏙 골라서 무적권을 적용시키고 싶다는 것이다. 그렇게 하려면, 최대힙을 사용하면 된다!!!
다음은 알고리즘이다.
enemy 리스트를 순회하면서 다음과 같은 로직을 수행한다.
from heapq import heappush, heappop
def solution(n, k, enemy):
rounds = len(enemy)
#무적권이 충분한 경우
if k >= rounds:
return rounds
#그렇지 않은 경우
answer = 0
heap = []
for ene in enemy:
#일단 병사 소모할 수 있으면 소모하여 heappush(최대힙이니까 음수로 저장)
if n >= ene:
n -= ene
heappush(heap, -ene)
#병사 소모할 수 없다면 (n < ene)
else:
#근데 무적권이 있다면, 무적권을 소모하고 n에 heap[0]을 더한 후, 현재 ene를 막는 데 쓴다.
#그리고 heappush(heap, -ene) 한다.
if k > 0 and heap:
heappush(heap, -ene)
n -= heappop(heap)
k -= 1
n -= ene
#무적권은 있는데 여태까지 heap에 쌓아둔 게 없다면, 무적권만 소모한다.
elif k > 0 and not heap:
k -= 1
#병사도 없고 무적권도 없다면, 겜 끝
else:
break
answer += 1
return answer