연습장/백준(BOJ) 문제풀이
[백준 11286] 절댓값 힙 with Python
Tesseractjh
2021. 9. 6. 23:13
문제 링크
https://www.acmicpc.net/problem/11286
11286번: 절댓값 힙
첫째 줄에 연산의 개수 N(1≤N≤100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 0이 아니라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0
www.acmicpc.net
풀이
import sys
class Heap:
def __init__(self, L=[]):
self.arr = L
def compare(self, a, b):
if abs(self.arr[a]) > abs(self.arr[b]):
return True
elif abs(self.arr[a]) < abs(self.arr[b]):
return False
else:
return self.arr[a] > self.arr[b]
def heapify_down(self, k, n):
while 2*k+1 < n:
L, R = 2*k+1, 2*k+2
if L < n and self.compare(k, L):
m = L
else:
m = k
if R < n and self.compare(m, R):
m = R
if m != k:
self.arr[k], self.arr[m] = self.arr[m], self.arr[k]
k = m
else:
break
def heapify_up(self, k):
while k > 0 and self.compare((k-1)//2, k):
self.arr[k], self.arr[(k-1)//2] = self.arr[(k-1)//2], self.arr[k]
k = (k-1)//2
def insert_key(self, key):
self.arr.append(key)
self.heapify_up(len(self.arr)-1)
def delete_max(self):
if len(self.arr) == 0: return None
self.arr[0], self.arr[len(self.arr)-1] = self.arr[len(self.arr)-1], self.arr[0]
key = self.arr.pop()
self.heapify_down(0, len(self.arr))
return key
def is_empty(self):
return len(self.arr) == 0
N = int(sys.stdin.readline())
heap = Heap()
output = []
for i in range(N):
x = int(sys.stdin.readline())
if x == 0:
if heap.is_empty():
output.append(0)
else:
output.append(heap.delete_max())
else:
heap.insert_key(x)
print('\n'.join(map(str, output)))
직접 Heap 클래스를 구현하여 해결하였다.
compare 메서드는 a와 b를 인자로 받아서 arr[a]가 arr[b]보다 절댓값이 큰지,
만약 절댓값이 같다면 arr[a]가 음수인지 여부를 반환한다.
heap에 원소를 push할 때 또는 pop한 뒤에는 arr가 compare 메서드를 기준으로 정렬된다.
import sys
import heapq
N = int(sys.stdin.readline())
plus_heap = []
minus_heap = []
output = []
for _ in range(N):
x = int(sys.stdin.readline())
if x > 0:
heapq.heappush(plus_heap, x)
elif x < 0:
heapq.heappush(minus_heap, -x)
else:
if not plus_heap and not minus_heap:
output.append(0)
elif not plus_heap:
output.append(-heapq.heappop(minus_heap))
elif not minus_heap:
output.append(heapq.heappop(plus_heap))
elif plus_heap[0] < minus_heap[0]:
output.append(heapq.heappop(plus_heap))
else:
output.append(-heapq.heappop(minus_heap))
print('\n'.join(map(str, output)))
파이썬의 heapq 모듈을 활용하면 더 쉽게 해결할 수 있다.
heapq는 최소힙
heapq로 문제를 풀기 위해 plus_heap, minus_heap으로 두 개의 최소힙이 필요하다.
minus_heap에 push할 때는 양수로 만들어서 push하고, pop할 때는 pop된 원소를 다시 음수로 만들어줘야 한다.