문제
수가 하나씩 들어올 때마다 지금까지 입력된 수들의 중간값을 출력하는 문제다.
핵심 아이디어
- 최대 힙(maxq)과 최소 힙(minq)을 사용해서 중간값을 O(1)에 접근한다.
- maxq의 top이 항상 중간값이 되도록 유지한다.
- maxq의 크기는 minq의 크기와 같거나 1만큼 크도록 밸런싱한다.
- 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)
두 개의 힙으로 중간값을 실시간 관리하는 클래식한 테크닉이다.
댓글