zoukankan      html  css  js  c++  java
  • 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; 
    }
  • 相关阅读:
    [ Openstack ] Openstack-Mitaka 高可用之 环境初始化
    [ Openstack ] OpenStack-Mitaka 高可用之 概述
    Swift
    Swift
    报错
    归并排序
    堆排序
    插入排序
    早睡早起身体好
    用于查询的日期类型转换帮助类
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10192837.html
Copyright © 2011-2022 走看看