P1168 中位数

点击查看代码
#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就移动堆顶到另一侧③输出数量多的堆的堆顶 这样用两个堆维护了一段大根堆所有元素小于大根堆的序列,又因为数量差的限制,较多的一侧堆顶就是中位数,很巧妙的设置
posted @ 2025-12-02 17:22  gosaky  阅读(0)  评论(0)    收藏  举报