• hdu3282 链表或者对顶堆


    维护序列的动态中位数

    第一次用链表做题。。感觉指针指来指去也挺麻烦的。。

    本题链表解法就是用数组模拟出一个链表,然后离线输入所有数,排序,按照输入顺序在链表里删除元素,一次性删掉两个,然后中位数指针对应移动即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    #define maxn 10004
    
    struct smc{
        int val,no;
        bool operator<(smc node)const{
            return val<node.val;
        }
    }a[maxn];
    
    int l[maxn],r[maxn],tt,p,n,mid;
    int ans[maxn],f[maxn];
     
    int main(){
        scanf("%d",&p);
        for(tt=1;tt<=p;tt++){
            scanf("%d%d",&mid,&n);
            printf("%d %d
    ",tt, n/2+1);
            mid=(1+n)/2;
            for(int i=1;i<=n;i++){scanf("%d",&a[i].val);a[i].no=i;}
            sort(a+1,a+1+n);
            for(int i=1;i<=n;i++){l[i]=i-1;r[i]=i+1;f[a[i].no]=i;}
            l[0]=l[1]=100,r[0]=1;
            for(int i=n;i>=1;i-=2){//一次减掉两个数 
                ans[i]=a[mid].val;
                if(f[i]<mid && f[i-1]<=mid) mid=r[mid];
                if(f[i]>mid && f[i-1]>=mid) mid=l[mid]; 
                if(f[i]==mid){
                    if(f[i-1]>mid) mid=l[mid];
                    else mid=r[mid];
                }    
                //从链表中删去这两个结点
                r[l[f[i]]]=r[f[i]];
                l[r[f[i]]]=l[f[i]];
                r[l[f[i-1]]]=r[f[i-1]];
                l[r[f[i-1]]]=l[f[i-1]];        
            }
            int cnt=0;
            for(int i=1;i<=n;i+=2){
                printf("%d ",ans[i]);
                if(++cnt>=10) puts(""),cnt=0;
            }
            puts("");
        }
        return 0;
    }

    网上另外一种解法是对顶堆,所谓对顶堆,就是建立一个小根堆q1,大根堆q2,每次读入的数如果比中位数大,那么就把它放入小根堆中,反之放入大根堆中,小根堆元素必须等于大根堆或者是大根堆+1,如果不符合要求就调整,小根堆堆顶元素即是中位数

    hdu和poj输出方式有点不一样

    #include<bits/stdc++.h>
    #define maxn 10005
    
    using namespace std;
    
    priority_queue<int,vector<int>,greater<int> >q1;//小根堆,堆顶中位数 
    priority_queue<int,vector<int>,less<int> >q2;//、大根堆 
    int T,n,x,cnt,tot,ans[maxn];
    
    void add(int x){
        if(q1.empty()){
            q1.push(x);
            return;
        }
        if(x>q1.top()) q1.push(x);
        else q2.push(x);
        while(q1.size()<q2.size()){
            q1.push(q2.top());
            q2.pop();
        }
        while(q1.size()>q2.size()+1){
            q2.push(q1.top());
            q1.pop();
        }
    }
    
    int main(){
        scanf("%d",&T);
        for(int tt=1;tt<=T;tt++){
            scanf("%d%d",&tt,&n);
            printf("%d %d
    ",tt,n/2+1);
            while(!q1.empty())q1.pop();
            while(!q2.empty())q2.pop();
            cnt=tot=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&x);
                add(x);
                if(i%2!=0) ans[tot++]=q1.top(); 
            }
            for(int i=0;i<tot;i++){
                if(i>0 && i%10==0) puts("");
                if(i%10) putchar(' ');
                printf("%d",ans[i]);
            }
            puts("");
        }
        return 0; 
    }
  • 相关阅读:
    JAVA8时间插入mysql少了8小时的解决办法
    Kubernetes 部署 Mysql 8.0 数据库(单节点)
    Spring Boot + MyBatisPlus,简直完美!
    美团面试官:生成订单后一段时间不支付订单会自动关闭的功能该如何实现?越详细越好~
    100道Java并发和多线程基础面试题大集合(含解答),这波面试稳了~
    windows端口占用快速查询解决方法
    解决github无法连接错误 OpenSSL SSL_connect: Connection was reset in connection to github.com:443
    Mysql:好好的索引,为什么要下推?
    漫画 | 程序员的悲哀是什么?
    聊聊那些年的骚操作!!!
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10192837.html
Copyright © 2020-2023  润新知