Programming/백준

[골드 2] 백준 1655 - 가운데를 말해요 (파이썬)

pental 2025. 7. 2. 16:44

https://www.acmicpc.net/problem/1655

풀이

  • max_pq는 왼쪽 절반, 즉 중간값 이하를 담고 최대 힙으로 운용한다. (파이썬에서는 -값을 넣어 사용)
  • min_pq는 오른쪽 절반, 즉 중간값 초과를 담고 최소 힙으로 운용한다.
  • 입력값과 max_pq, min_pq에서 하나씩 빼서 총 3개의 숫자 후보를 만들고 정렬 후 재분배한다.
  • 중간값은 항상 max_pq의 top인 -max_pq[0]이 된다.
max_pq = [1e9]
min_pq = [1e9]

1e9를 미리 넣어둔다. 즉 힙이 비어있을때 heappop 하기 위한 임시값이다.

하지만 이건 비정상적인 초기값이고, 결과적으로 정답이 이상해 질 수 도 있다.

a = [A[i]]
a.append(-heapq.heappop(max_pq))
a.append(heapq.heappop(min_pq))
a.sort()

현재 숫자 + 양쪽 합에서 하나씩 빼서 총 3개로 구성한다.

정렬 후 다시 힙에 재분배한다.

while len(max_pq) < (i + 2) // 2 + 1 :
    heapq.heappush(max_pq, -a[pos])
    pos += 1

while pos < 3 :
    heapq.heappush(min_pq, a[pos])
    pos += 1

max_pq는 (i + 1) // 2개의 원소를 가져야 한다. 즉 중간값이 항상 top에 위치하도록 강제한다.

남은 값은 min_pq로 넘긴다.

문제점은 다음과 같다.

  • 1e9를 초깃값으로 힙에 넣어두는 방식은 의도치 않게 잘못된 값이 출력될 수 있다.
  • 처음 입력이 1이라도 1e9와 함께 섞이므로 이상한 값 나올수 있다.
  • 예를 들어 입력이 [1]이면 출력이 1이어야 하나, 네 코드에서는 1e9까지 섞여서 오작동 할 수 도 있다.

코드

# 백준 1655 - 가운데를 말해요
# 분류 : 우선순위 큐

import sys
import heapq

input = sys.stdin.readline

N = int(input())
A = [int(input()) for _ in range(N)]

max_pq = [1e9]
min_pq = [1e9]

for i in range(N) :
    a = [A[i]]
    a.append(-heapq.heappop(max_pq))
    a.append(heapq.heappop(min_pq))
    a.sort()

    # i + 1 -> (i + 2) // 2 + 1
    pos = 0
    while len(max_pq) < (i + 2) // 2 + 1 :
        heapq.heappush(max_pq, -a[pos])
        pos += 1
    
    while pos < 3 :
        heapq.heappush(min_pq, a[pos])
        pos += 1

    print(-max_pq[0])