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