[堆] HDU4006 The kth great number

看标题以为是区间第K大,准备去水一发,结果是整体第K大,由于没有删除操作,维护一个小根堆就行了,保持top是第k大,比top小的加入堆对top没有影响,也永远用不上,比top大的加入就更新top,保持堆有k个元素就行了。

数据结构没什么可以说的,主要是学习了STL的用法,用vector自带的堆函数,用优先队列,其实优先队列本身就是堆实现的。

不过还是不会手写堆,STL大法好。

下面是vector写的。

#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<climits>
#include<list>
#include<iomanip>
#include<stack>
#include<set>
#include<ctime>
#define pb push_back
#define pii pair<int,int>
#define LL long long int
using namespace std;
int main(){
    int n,k,tmp;
    char op;
    while(scanf("%d%d%*c",&n,&k)!=EOF){
        vector<int>H;
        for(int i=0;i<k;++i){
            scanf("%c %d%*c",&op,&tmp);
            H.pb(tmp);
        }
        n-=k;
        make_heap(H.begin(),H.end(), greater<int>() ); //把一个vector做成一个堆 STL自带的功能 greater<int>算子表示是一个小根堆
        while(n--){
            int top=*(H.begin()); //始终保持顶端是第K大就行了 题目说了询问一定合法
            do{op=getchar();}while(op!='I'&&op!='Q');
            if(op == 'I'){
                scanf("%d%*c",&tmp);
                if(tmp>top){                                        //比top小的对第K大没有影响 比top大的时候就更新top
                    pop_heap(H.begin(),H.end(), greater<int>() );   //删除元素 先用pop_heap维护堆 记得用greater算子维护小根堆
                    H.pop_back();                                   //再用pop_back删除元素
                    H.pb(tmp);                                      //先把元素加入vector
                    push_heap(H.begin(),H.end(), greater<int>() );  //再用push_heap维护堆
                }
            }
            else printf("%d\n",top);
        }
    }
}
优先队列写的。

#include<cstdio>
#include<queue>
#include<iostream>
#include<functional>
#include<algorithm>
using namespace std;
int main(){
    int n,k,tmp;
    char op;
    while(scanf("%d%d%d",&n,&k)!=EOF)
    {
        priority_queue<int,vector<int>, greater<int> > q;
        for(int i=0;i<k;++i){
            scanf("%c %d%*c",&op,&tmp);
            q.push(tmp);
        }
        n-=k;
        while(n--){
            scanf("%c%*c",&op);
            if(op=='I'){
                scanf("%d%*c",&tmp);
                if(tmp>q.top()){
                    q.pop();
                    q.push(tmp);
                }
            }
            else printf("%d\n",q.top());
        }
    }
}
可以看出优先队列比vector简便,不过以前不知道vector可以做堆,也算是学习了。

还有HDU的编译环境,大小算子是在functional头文件里面,这题就CE一发,我记得以前也用过,没什么问题来着,不过以后还是加上functional,以免CE冤枉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值