正在加载

请稍等

第一次加载可能稍慢

P1168 中位数 题解

Author: ljc Time: 2025/09/22 Tag: 题解

P1168 中位数

P1168 中位数 - 洛谷

题解

只需要维护一个中间大小的数,我们可以试着使用两个优先队列(一个大根堆,用于记录比中位数小的数,堆顶为最小数中的最大值;一个小根堆,同前,用于记录比中位数大的数,堆顶为最大数中的最小值),使两个队列的长度差小于1,每次只需要获取中间的值即可。

我的代码中设置大根堆默认多一个,每次查询只需要输出大根堆的堆顶即可。(小根堆使用负数代替)

Code

#include<bits/stdc++.h>
using namespace std;
int n,a[100010],x;
priority_queue<int> pmx; // 符号+  比中位数小或等于的数
priority_queue<int> pmi; // 符号-  比中位数大于的数
int main(){
    cin >> n;
    for(int i=1;i<=n;i++)cin >>a[i];
    cout << a[1] << endl;pmx.push(a[1]); // 先处理第一个数
    for(int i=3;i<=n;i+=2){
        for(int j=1;j>=0;j--){ // 每次处理两个
            if(pmi.size()==0) x = pmx.top();
            else x = -pmi.top(); // 防止堆中无元素导致错误

            if(x<a[i-j])pmi.push(-a[i-j]); // 添加元素
            else pmx.push(a[i-j]);
        }
        // 将两个堆的长度差减小
        while(pmx.size()>pmi.size()+1){
            pmi.push(-pmx.top());
            pmx.pop();
        }
        while(pmx.size()<=pmi.size()){
            pmx.push(-pmi.top());
            pmi.pop();
        }
        cout << pmx.top() << endl; // 输出
    }
    return 0;
}

声明:本博客由作者原创,转载请标明出处。