[BOJ] 1655 가운데를 말해요 (Python3)

1 분 소요

문제

백준이는 동생에게 “가운데를 말해요” 게임을 가르쳐주고 있다. 백준이가 정수를 하나씩 외칠때마다 동생은 지금까지 백준이가 말한 수 중에서 중간값을 말해야 한다. 만약, 그동안 백준이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 말해야 한다.

예를 들어 백준이가 동생에게 1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2, 5를 차례대로 말해야 한다. 백준이가 외치는 수가 주어졌을 때, 동생이 말해야 하는 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에는 백준이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 백준이가 외치는 정수가 차례대로 주어진다. 정수는 -10,000보다 크거나 같고, 10,000보다 작거나 같다.

출력

한 줄에 하나씩 N줄에 걸쳐 백준이의 동생이 말해야 하는 수를 순서대로 출력한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
예제 입력 1  
7
1
5
2
10
-99
7
5
예제 출력 1  
1
1
2
2
2
2
5

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import heapq
import sys
input = sys.stdin.readline

n = int(input())
leftHeap = []
rightHeap = []
answer = []

for _ in range(n):
    num = int(input())
    if len(leftHeap) == len(rightHeap): 
        heapq.heappush(leftHeap, (-num, num))
    else:
        heapq.heappush(rightHeap, (num, num))
        
    if rightHeap and leftHeap[0][1] > rightHeap[0][0]:
        max = heapq.heappop(leftHeap)[1]
        min = heapq.heappop(rightHeap)[0]
        heapq.heappush(leftHeap, (-min, min))
        heapq.heappush(rightHeap, (max, max))
    answer.append(leftHeap[0][1])
    
for i in answer:
    print(i)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
7
1
5
2
10
-99
7
5
1
1
2
2
2
2
5

문제풀이

처음에는 정렬이랑 그냥 우선순위큐로 풀었는데 아무리 해도 시간초과가 떠서 해답을 찾아봤다.
중간값보다 작은 leftHeap과 rightHeap으로 두 힙으로 나눈뒤, leftHeap은 최대힙으로 구성하고, rightHeap은 최소힙으로 구성한다.

두 힙의 개수가 같을때는 leftHeap에 Heappush해주고, 두 힙의 개수가 다를 때는 rightHeap에 Heappush해준다.

이렇게 Heappush하다보면 leftHeap에 rightHeap보다 큰 값이 들어갈때가 있는데, 이를 보정하기 위해 if문을 두어 두 Heap의 맨 위 값을 비교 한 뒤 만약 leftHeap이 rightHeap보다 크다면 두 값을 교체해준다.

카테고리:

업데이트:

댓글남기기