您的位置:首页 > 其它

poj 1442 Black Box

2012-03-14 10:05 393 查看
/*

题意:向一个容器中不断的添加m个数,然后有n个查询,
每次查询在插入的前u个数中第i个小的数,i初始值是1,每查询一次就自增1
sample:        7 4            3 1 -4 2 8 -1000 2                1 2 6 6
第1次查询:u=1,即插入 3 , 第1 小的数是 3
第2次查询:u=2,即插入 3 1, 第2 小的数是 3
第3次查询:u=6,即插入 3 1 -4 2 8 -1000, 第3 小的数是 1
第3次查询:u=6,即插入 3 1 -4 2 8 -1000, 第4 小的数是 2
所以输出为: 3 3 1 2
思路: 要查询第 i 大的数,需要维护大顶堆和小顶堆,让大顶堆的堆顶小于小顶堆的堆顶
即大顶堆所有元素都小于小顶堆的所有元素.每次插入新元素时,让大顶堆的规模保持为 i-1
则小顶堆的堆顶就是第 i 小的数了

*/
#include <iostream>        //大顶堆和小顶堆,查询第i小的数
#include <queue>
using namespace std;
int m,n,arr[30002],res[30002];
int main()
{
priority_queue<int> q1;    //大顶堆
priority_queue<int,vector<int>,greater<int> > q2;    //小顶堆
cin>>m>>n;
for(int i=1;i<=m;++i)
cin>>arr[i];
int u,cur=0,cnt=0,rear=0;
while(n--)
{
cin>>u;
while(cur<u)
{
int num=arr[++cur];        // cur 指当前处理的arr数组的下标
//以下两种操作都是让大顶堆的规模保持不变
if( !q1.empty() && num<q1.top() )    // 新元素小于大顶堆q1的最大值(堆顶),则需要先弹出q1的堆顶,并把它压入小顶堆,再把新元素压入到大顶堆
{
int t=q1.top();
q1.pop();
q2.push(t);
q1.push(num);
}
else    // 新元素比大顶堆q1的最大值(堆顶)还大,则压入小顶堆
{
q2.push(num);
}
}
if(q1.size()<cnt)    // cnt 指大顶堆要达到的规模
{
int t=q2.top();
q2.pop();
q1.push(t);
}
res[rear++]=q2.top();    //小顶堆的堆顶就是第cnt+1小的数
cnt++;
}
for(int i=0;i<rear;++i)
cout<<res[i]<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: