POJ 1442 Black Box

来源:互联网 发布:淘宝卖家手机端 编辑:程序博客网 时间:2024/05/01 18:21

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

题意:就是两个操作,add是加入一个数,get是获取第i小的数,每次get的时候i都加1.输入的话,第一行a数组就是所有的需要逐次加进队列的数字,第二行u数组代表当队列中元素的个数为多少时执行一次get操作。

解析:自己做的话曾经想到用set,但是最后的话因为set无法查询第k小的数,只能查询确定值的数。所以用迭代器从begin()开始加的话,最后超时了。看了大牛的博客才发现原来可以用两个优先队列来维护。一个是大堆,从大到小,一个是小堆,从小到大。其中要使小堆的堆顶始终大于大堆的堆顶。这样的话小堆堆顶存储的始终就是第i小的了。

//算法:用两个优先队列的堆来维护,其中q1为从小到大排列,q2从大到小排列。每次保证q1堆顶的数字大于q2堆顶的数据,//则q1堆顶的数据就是第i小的数据#include<stdio.h>#include<string.h>#include<queue>#include<vector>#include<functional>#define INF 31000using namespace std;int m,n,cnt,a[INF],u;priority_queue<int,vector<int>,greater<int> > q1;//从大到小priority_queue<int,vector<int>,less<int>> q2;//从小到大int main(){while(scanf("%d%d",&m,&n) != EOF){memset(a,0,sizeof(a));for(int i = 1 ; i <= m ; i ++)scanf("%d",&a[i]);int cnt = 1;for(int i = 1; i <= n ; i ++){scanf("%d",&u);for(;cnt <=  u;cnt++){q1.push(a[cnt]);if(!q2.empty() && q1.top() < q2.top())//保证每次q1堆顶都大于q2堆顶,否则交换q1,q2的堆顶来保证q1堆顶大于q2{int t = q1.top();q1.pop();q1.push(q2.top());q2.pop();q2.push(t);}}printf("%d\n",q1.top());q2.push(q1.top());//这两行保证了每次都是第cnt(即i)小的数据都在q1的堆顶q1.pop();//cnt = 1时,q2零个元素,cnt = 2,q2一个元素}}return 0;}


原创粉丝点击