[堆] HDU4006 The kth great number

来源:互联网 发布:域名查询 美橙互联 编辑:程序博客网 时间:2024/06/05 18:49

看标题以为是区间第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 intusing 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
原创粉丝点击