BOJ-1655 가운데를 말해요
https://www.acmicpc.net/problem/1655
문제 소개
수가 하나씩 추가될 때마다 지금까지 추가된 수들의 중간값을 출력하는 문제이다. 우선순위 큐를 이용하여 해결하였다. 힙을 사용하기 위해 heapq
모듈을 import
하였다.
문제 풀이
먼저 중간값보다 작은 수들이 들어갈 힙을 heapL
, 중간값보다 큰 수들이 들어갈 힙을 heapR
이라고 선언한다.
heapL
은 최대 힙이며, heapR
은 최소 힙으로 동작한다. 그리고 왼쪽 힙과 오른쪽 힙을 번갈아 가며 입력된 정수를 push
하게 되는데, push
직후 왼쪽 힙의 최대값이 오른쪽 힙의 최소값보다 크다면 그 두 값을 pop
한 후 서로 반대 힙으로 push
한다.
위 동작을 통해 언제나 heapL
의 최대값은 heapR
의 최소값보다 작거나 같게 된다.
중간값 결정
인덱스 i
를 1
부터 n
까지로 하여 왼쪽 힙부터 입력을 받게 하면 중간값은 아래와 같이 결정된다.
n
이 홀수인 경우 :
heapL
의 길이가heapR
의 길이보다 1 크며,heapL[0]
은 중간값이다.n
이 짝수인 경우 :heapL
과heapR
의 길이는 동일하며,heapL[0]
은 문제의 조건에 맞는 수이다.
즉, 언제나 heapL[0]
이 중간값이 된다.
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import heapq
from sys import stdin
input = stdin.readline
n = int(input())
heapL = []
heapR = []
for i in range(1, n + 1):
if i % 2 == 0:
heapq.heappush(heapR, int(input())) # 오른쪽 힙은 최소 힙
else:
heapq.heappush(heapL, -int(input())) # 왼쪽 힙은 최대 힙
try:
if -heapL[0] > heapR[0]:
heapq.heappush(heapR, -heapq.heappop(heapL))
heapq.heappush(heapL, -heapq.heappop(heapR))
except IndexError:
pass
# print(f"heapL : {heapL}")
# print(f"heapR : {heapR}")
print(-heapL[0])
try except
문을 사용한 이유는 i
가 1일 때, heapR
이 빈 리스트인 상황을 넘기기 위해서이다.
주석처리한 2개의 print
문으로는 매 반복마다 두 힙의 내용을 확인할 수 있다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.