Blog / Algorithm / 백준 1655번 가운데를 말해요 — 힙 C++ 풀이
Algorithm

백준 1655번 가운데를 말해요 — 힙 C++ 풀이

백준 1655번 가운데를 말해요 풀이. 최대 힙과 최소 힙 두 개의 밸런싱으로 수가 들어올 때마다 중간값을 실시간으로 구하는 C++ 코드와 풀이 과정을 정리한다.

문제

BOJ 1655 - 가운데를 말해요

수가 하나씩 들어올 때마다 지금까지 입력된 수들의 중간값을 출력하는 문제다.

핵심 아이디어

  1. 최대 힙(maxq)과 최소 힙(minq)을 사용해서 중간값을 O(1)에 접근한다.
  2. maxq의 top이 항상 중간값이 되도록 유지한다.
  3. maxq의 크기는 minq의 크기와 같거나 1만큼 크도록 밸런싱한다.
  4. maxq의 top은 항상 minq의 top보다 작거나 같아야 한다.

풀이

#include <iostream>
#include <queue>

using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n, size = 0;

    priority_queue<int> maxq;
    priority_queue<int, vector<int>, greater<int>> minq;

    cin >> n;

    for (int i = 0; i < n; i++) {
        int m;
        cin >> m;

        if (size == 0) {
            maxq.push(m);
        } else if (size == 1) {
            if (m > maxq.top()) {
                minq.push(m);
            } else {
                minq.push(maxq.top());
                maxq.pop();
                maxq.push(m);
            }
        } else {
            maxq.push(m);

            if (maxq.top() > minq.top()) {
                minq.push(maxq.top());
                maxq.pop();

                if (minq.size() > maxq.size()) {
                    maxq.push(minq.top());
                    minq.pop();
                }
            }

            if (maxq.size() - minq.size() > 1) {
                minq.push(maxq.top());
                maxq.pop();
            }
        }

        cout << maxq.top() << '\n';
        size++;
    }

    return 0;
}

시행착오

  • endl 대신 '\n'을 사용해야 시간 초과를 피할 수 있었다. endl은 매번 버퍼를 flush하기 때문에 출력이 많은 문제에서 치명적이다.

복잡도

  • 시간: O(N log N) — 각 삽입마다 힙 연산 O(log N)
  • 공간: O(N)

두 개의 힙으로 중간값을 실시간 관리하는 클래식한 테크닉이다.

댓글

블로그 목록으로
ACHIEVEMENT UNLOCKED
LOADING...
SCORE 000000
HITS
0