pku 1442 Black Box 优先队列

http://poj.org/problem?id=1442

看了好几遍才懂了题意:就是给你m个数(要进入box的),然后是n个数u[i .. n],每个u[i]表示询问:当前u[i]个数进入box之后,求第i小的数。。

用两个优先队列分别建立大顶堆,小顶堆:小顶堆存放新加进来的数,大顶堆存放前边出现的数。。。

小顶堆存放新加进来的数并且维持着小顶堆里面的最小值,一定大于大顶堆里面的所有值。大顶堆记录的是当前所有出现的数的最小的几个(个数是上一次出现的序列的个数)

例如u[2] = 2-->u[3] = 6

q2 : 3,1

q1: -4

=>

q2: 1,-4 

q1: 3;

=>

q2: 1,-4

q1: 2,3

=>

q2:1,-4

q1: 2,3,8

=>

q2:1,-4

q1: 2,3,8,-1000

---》

q2:-1000,-4

q1: 2,3,8,1

输出1

这里q2的个数的是u[2] = 2 是所有进入box的个数,并且与q1一起维持着q2中放的是最小的。。

View Code
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define maxn 30007
using namespace std;

int ar[maxn];
struct cmp1
{
bool operator () (int &a,int &b)
{
return a > b;
}
};
struct cmp2
{
bool operator () (int &a,int &b)
{
return a < b;
}
};
//小顶堆
priority_queue<int,vector<int>,cmp1>q1;
//大顶堆
priority_queue<int,vector<int>,cmp2>q2;

int main()
{
int i,n,m,u;
scanf("%d%d",&m,&n);
for (i = 0; i <m; ++i) scanf("%d",&ar[i]);
int ct = 0;
for (i = 0; i < n; ++i)
{
scanf("%d",&u);
while (ct < u)
{
q1.push(ar[ct++]);
//如果新加入的序列的最小值小于原先序列的最大值
//那么此最小值肯定会在原来的序列的前面,也就是说此最小值已经脱离了
//解域,而把原来序列的最大值加入解域。
if (!q2.empty() && q1.top() < q2.top())
{
int t = q1.top();
q1.pop();
q1.push(q2.top());
q2.pop();
q2.push(t);
}
}
printf("%d\n",q1.top());
q2.push(q1.top());
q1.pop();
}
return 0;
}



posted @ 2012-04-02 19:44  E_star  阅读(208)  评论(0编辑  收藏  举报