点击查看代码
#include <bits/stdc++.h>
using namespace std;
priority_queue<int> q1; // 大根堆,存较小一半
priority_queue<int, vector<int>, greater<int>> q2; // 小根堆,存较大一半
int main() {
int n, x;
cin >> n >> x;
q1.push(x);
cout << q1.top() << endl;
for (int i = 2; i <= n; i++) {
cin >> x;
// 放入合适的堆
if (x > q1.top()) q2.push(x);
else q1.push(x);
// 调整平衡
//核心就在于这一步,这样的维护使得较小部分的最大值也要小于较大部分的最小值,较大部分的最小值也小于较小部分的最大值,加上二者差值不大于1的维护,使得二者数量不相等时,数量较多的堆的堆顶就是中位数
while (abs((int)q1.size() - (int)q2.size()) > 1) {
if (q1.size() > q2.size()) {
q2.push(q1.top());
q1.pop();
} else {
q1.push(q2.top());
q2.pop();
}
}
// 奇数项输出中位数
if (i & 1) {
if (q1.size() > q2.size()) cout << q1.top() << endl;
else cout << q2.top() << endl;
}
}
return 0;
}
很巧妙的维护思路①大于大根堆就存到小根堆②数量差大于1就移动堆顶到另一侧③输出数量多的堆的堆顶
这样用两个堆维护了一段大根堆所有元素小于大根堆的序列,又因为数量差的限制,较多的一侧堆顶就是中位数,很巧妙的设置