우선 순위 큐를 사용하여 가장 작은 수를 추출해야 하는 문제.
이번 문제는 우선순위 큐와 힙 자료구조을 사용하여 풀어야 하는 문제였다.
우선순위 큐와 관련된 문제를 찾던 중, 그나마 만만해보여서 (...) 선택하였다.
키가 큰 거인을 꺼내 키를 확인하고, 이것이 센티보다 작은지를 파악해야 한다.
N
명의 거인들의 키를 대상으로 센티가 T
번만큼의 뿅망치질을 진행한다.
뿅망치에 맞은 거인은 키의 절반을 잃고, 키가 1일 경우 더 이상 줄지 않는다.
결국 이는 거인의 키가 담긴 List
를 우선순위 큐를 통해 최댓값부터 뽑아야 한다.
따라서 다음과 같은 로직을 통해 문제를 풀어나갈 수 있을거라 기대하였다.
N
개의 자연수가 담긴 우선순위 큐에서, 가장 값이 큰 거인의 키를 뽑는다.T
회 반복한 후, 우선순위 큐 내에서 가장 큰 거인의 키를 뽑는다.Python에서 지원하는 heapq 라이브러리는 아래와 같은 함수를 추가로 지원한다.
heapq.heapreplace(heap, elm)
: 힙에서 가장 작은 원소를 뺀 뒤, 새로운 값을 넣음heaqp.heappushpop(heap, elm)
: 힙에서 특정 원소를 넣은 뒤, 가장 작은 원소를 뺌처음에 거인의 키를 절반으로 줄인 후에 이를 다시 넣는 과정이 꽤나 번거로웠다.
그래서 관련 자료를 찾아보니 상단의 함수들이 더 존재한다는 것을 알게 되었다.
import sys
import heapq
read = sys.stdin.readline
N, centi_height, T = map(int, read().split())
heap = [-int(read()) for _ in range(N)]
heapq.heapify(heap)
count = 0
for _ in range(T):
if -heap[0] < centi_height or -heap[0] == 1:
break
heapq.heapreplace(heap, -(-heap[0] // 2))
count += 1
if -heap[0] < centi_height:
print('YES', count, sep='\n')
else:
print('NO', -heap[0], sep='\n')
최대 힙을 사용할 경우 값이 음수로 나오기 때문에 이를 다시 양수로 변환해야 한다.
나는 처음에 abs()
함수를 사용하려 했으나, 변수 앞에 -
부호를 붙여도 괜찮았다.
앞으로는 입력받은 값을 음수로 변환시키고자 할 때는, 위의 코드처럼 작성해야겠다.
처음에 값을 2로 나누는 과정에서 음수를 양수로 변환시키지 않았더니 계산이 꼬였다.
따라서 괄호를 추가로 두어 양수로 변환된 값을 2로 나누고, 이를 다시 음수로 변경했다.
https://github.com/RookieAND/BaekJoonCode
날이 더워지다 보니 공부도, 다른 것도 의욕이 나지 않는 상태가 계속되고 있다.
하지만 언제까지고 포기할 수는 없는 법. 꾸준히 조금씩 풀어나가보자.