一开始就没有深刻理解,认为要做的事儿是:
设时间为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;
}