
난이도 : 골드 2
유형 : 우선순위 큐
https://www.acmicpc.net/problem/2696
여러 테스트케이스가 주어지고, 각 테스트마다 수열이 최대 10,000개까지 주어진다.
이 수열을 앞에서부터 하나씩 보면서, 홀수 번째 수를 입력받을 때마다 중앙값을 출력하는 문제이다.
출력은 한 줄에 최대 10개까지만 출력해야한다.
최대큐와 최소큐 두개의 큐에 수들을 저장한다.
중앙값을 최대큐인 -minheap 에 넣을 것이다.
그래야 우리가 -minheap[0] 을 통해 바로 중앙값을 가져올 수 있기 때문이다.
최소 큐에 넣으면 중앙값을 바로 가져올 방법이 없다.
import heapq
import sys
input = sys.stdin.readline
T = int(input()) # 테스트 케이스 수
for _ in range(T):
m = int(input()) # 이 테스트케이스에서 입력될 숫자 개수
nums = []
# 숫자가 여러 줄에 걸쳐서 들어오므로, 전체 m개가 될 때까지 입력 받음
while len(nums) < m:
nums += list(map(int, input().split())) # +=로 이어붙여야 덮어쓰기 안됨
max_heap = [] # 중앙값 이하를 저장하는 최대 힙 (파이썬은 min-heap이라 음수로 저장)
min_heap = [] # 중앙값 초과를 저장하는 최소 힙
result = [] # 홀수 번째 입력마다 저장할 중앙값 리스트
for i in range(m):
num = nums[i]
# max_heap이 비었거나, 현재 수가 중앙값 이하일 경우 max_heap에 저장
if not max_heap or num <= -max_heap[0]:
heapq.heappush(max_heap, -num)
else:
# 중앙값 초과일 경우 min_heap에 저장
heapq.heappush(min_heap, num)
# 두 힙의 크기를 맞춰줌 (max_heap은 항상 min_heap보다 같거나 1개 더 많아야 함)
if len(max_heap) > len(min_heap) + 1:
heapq.heappush(min_heap, -heapq.heappop(max_heap)) # max → min 이동
elif len(min_heap) > len(max_heap):
heapq.heappush(max_heap, -heapq.heappop(min_heap)) # min → max 이동
# 홀수 번째 입력일 경우 (0-based index 기준), 중앙값 저장
if i % 2 == 0:
result.append(-max_heap[0]) # 중앙값은 항상 max_heap 루트에 있음
print(len(result)) # 중앙값의 개수 출력
for i in range(0, len(result), 10):
# 결과를 10개씩 끊어서 출력
print(' '.join(map(str, result[i:i+10])))
최대 큐와 최소 큐 두개다 활용하는 우선순위 큐의 화룡점정같은 문제.
잘 이해 한다면 우선순위 큐를 잘 다룰 수 있을 것 같다.