• 《算法竞赛进阶指南》0x05排序 POJ3784 对顶堆动态维护中位数


    题目链接:http://poj.org/problem?id=3784

    对顶堆算法:输入M个数的时候,将其中1~[M/2]个小的数存入大顶堆,将剩余数存入小顶堆,如果大顶堆中的数的数量大于[M/2]就讲堆顶元素取出扔到小顶堆中去,

    当扫描到计数数量时,输出小顶堆的堆顶元素,也就是第[M/2]+1大的元素,这个元素就是整个序列的中位数,时间复杂度约为O(nlogn)。

    代码如下:

    #include<iostream>
    #include<queue>
    using namespace std;
    typedef unsigned int ui;
    typedef long long ll;
    typedef unsigned long long ull;
    #define pf printf
    #define mem(a,b) memset(a,b,sizeof(a))
    #define prime1 1e9+7
    #define prime2 1e9+9
    #define pi 3.14159265
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define scand(x) scanf("%llf",&x) 
    #define f(i,a,b) for(int i=a;i<=b;i++)
    #define scan(a) scanf("%d",&a)
    #define mp(a,b) make_pair((a),(b))
    #define P pair<int,int>
    #define dbg(args) cout<<#args<<":"<<args<<endl;
    #define inf 0x7ffffff
    inline int read(){
        int ans=0,w=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
        while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
        return ans*w;
    }
    int n,m,t;
    const int maxn=1e5+10;
    const ll mod=10000;
    priority_queue<int,vector<int>,less<int> >q1;// 大根堆
    priority_queue<int,vector<int>,greater<int> >q2;//小根堆
    int main()
    {
       // freopen("input.txt","r",stdin);
       // freopen("output.txt","w",stdout);
       t=read();
       int num;
       while(t--){
               while(q1.size())q1.pop();
            while(q2.size())q2.pop();
            cin>>num>>n;
            cout<<num<<" "<<(n+1)/2<<endl;
            int a;
            cin>>a;
            cout<<a<<" ";//1为奇数,输出第一个元素 
            q2.push(a);//中位数在小根堆中 
            int cnt=1;
            f(i,2,n){
                scanf("%d",&a);
                if(a<q2.top())q1.push(a);
                else q2.push(a);
                int s=q1.size();
                if(s>i/2){//大顶堆中的元素过多,调整到小顶堆中去 
                    q2.push(q1.top());
                    q1.pop();
                }
                if(s<i/2){
                    q1.push(q2.top());
                    q2.pop();
                }
                if(i%2){//输出奇数时刻的中位数 
                    cout<<q2.top()<<" ";
                    if(++cnt%10 == 0)cout<<endl;//每行十个数 
                }
            }
            if(cnt%10 != 0)
            cout<<endl; 
       }
    }
  • 相关阅读:
    低水平博士是提升科研生涯的毒药
    MATLAB——axis
    MATLAB——PLOT绘图
    漫谈正态分布的生成
    一位创业者创业失败后,成功的做了一个创业孵化器!
    iOS 使用Method Swizzling隐藏Status Bar
    翻转View
    【iOS】Plist-XML-JSON数据解析
    Android流式布局实现
    S3C2416裸机开发系列十六_sd卡驱动实现
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13131778.html
Copyright © 2020-2023  润新知