poj 2051 (用Priority_queue求解

   一开始就没有深刻理解,认为要做的事儿是:

   设时间为p1,p2,...pn.则需要从  p1,p2,p3...pn; 2*p1,2*p2,2*p3...2*pn;... K*p1,K*p2,..K*pn;中找到最小的前K个。

   这样的话最坏情况有10^7个数据,辛辛苦苦用了set ,qsort,priority_queue等方法均超时。

   实在受不了了,看了一下别人的思路,是这样的:

   先插入p1,p2,...pn,然后从中选出最小的pi,然后把pi时间向后设置(加上周期)之后放入原来的队列中,即变为 p1,p2,...new_pi,..pn;

这样重复,只需要插入,删除K次数据就能找到前K个。

正确性:为什么每次新插入的元素是删除的最小元素的周期加上周期? 因为只有最小元素的周期加上周期有可能是最小的。其他元素的加上周期只会变的更大,不可能成为整个数列的最小。


优先级队列的精髓在于优先级! 具体问题中如何决定优先考虑对象很重要。

自己一开始的方法压根就没有优先级。哎,对队列的理解太浅了。


/*
 * =====================================================================================
 *
 *       Filename:  2051.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2012年04月24日 21时46分57秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  MaZheng (blog.csdn.net/mazheng1989), mazheng19891019@gmail.com
 *        Company:  Dalian University Of Technology
 *
 * =====================================================================================
 */


#include<string.h>
#include<stdio.h>
#include<queue>
using namespace std;

#define	Data_Num 1005			/*  */
class Argus{
	public:
		int q_num;
		int time;
		int period;
		bool operator()(const Argus &arg1,const Argus &arg2)const
		{
			return arg1.q_num<arg2.q_num;
		}
		bool operator<(const Argus &arg)const
		{
			if(time!=arg.time)
			{
				return time>arg.time;
			}
			return q_num>arg.q_num;
		}
};


//please declare parameters here.


//please declare functions here.

int main()
{
	 
	priority_queue<Argus> myQueue;
	//input your ...
	char str[20];
	int K,q_num,period;
	while(scanf("%s",str)&&strcmp(str,"#"))
	{
		scanf("%d %d\n",&q_num,&period);
		//		printf("%s %d %d\n",str,q_num,period);
		Argus tmp;
		tmp.q_num=q_num;
		tmp.time=period;
		tmp.period=period;
		myQueue.push(tmp);
	}
	scanf("%d",&K);
	while(K--)
	{
			Argus tmp=myQueue.top();
			printf("%d\n",tmp.q_num);
			myQueue.pop();
			Argus new_tmp;
			new_tmp.q_num=tmp.q_num;
			new_tmp.period=tmp.period;
			new_tmp.time=tmp.time+tmp.period;
			myQueue.push(new_tmp);
	}
	return 0;
}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值