POJ 1442 Black Box

题目链接: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 31000
using 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;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值