优先队列 LA3135 阿格斯 简单多路归并

版权声明:抱最大的希望,为最大的努力,做最坏的打算。 https://blog.csdn.net/qq_37748451/article/details/86605398
A data stream is a real-time, continuous, ordered sequence of items. Some examples include sensor data, Internet traffic, financial tickers, on-line auctions, and transaction logs such as Web usage logs and telephone call records. Likewise, queries over streams run continuously over a period of time and incrementally return new results as new data arrives. For example, a temperature detection system of a factory warehouse may run queries like the following.

Query-1: �Every five minutes, retrieve the maximum temperature over the past five minutes.� Query-2: �Return the average temperature measured on each floor over the past 10 minutes.�
We have developed a Data Stream Management System called Argus, which processes the queries over the data streams. Users can register queries to the Argus. Argus will keep the queries running over the changing data and return the results to the corresponding user with the desired frequency.

For the Argus, we use the following instruction to register a query:

Register Q_num Period
Q_num (0 < Q_num ≤ 3000) is query ID-number, and Period (0 < Period ≤ 3000) is the interval between two consecutive returns of the result. After Period seconds of register, the result will be returned for the first time, and after that, the result will be returned every Period seconds.

Here we have several different queries registered in Argus at once. It is confirmed that all the queries have different Q_num. Your task is to tell the first K queries to return the results. If two or more queries are to return the results at the same time, they will return the results one by one in the ascending order of Q_num.

Input 
The first part of the input are the register instructions to Argus, one instruction per line. You can assume the number of the instructions will not exceed 1000, and all these instructions are executed at the same time. This part is ended with a line of �#�.

The second part is your task. This part contains only one line, which is one positive integer K (≤ 10000).

Output 
You should output the Q_num of the first K queries to return the results, one number per line.

Sample Input
Register 2004 200
Register 2005 300
#
5

Sample output
2004
2005
2004
2004
2005

题意:有N个任务,每个任务都有自己的时间间隔(就是每t秒请求执行一次)和任务id,这n个任务公用一个cpu,每次我们都执行时间靠前的,如果相同时间内有多个任务,就执行任务id小的,要求模拟出执行的前n个任务都是谁。

分析:操作系统里的先进先出

       用优先队列来维护每个触发器的下一个事件,然后每次从中取出最早发生的一个事件,重复k次。

        任意时刻优先队列里都是n个元素

先来复习一下优先队列:

优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大到小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。

优先级队列可以用向量(vector)或双向队列(deque)来实现(注意list container不能用来实现queue,因为list的迭代器不是任意存取iterator,而pop中用到堆排序时是要求randomaccess iterator 的!):
priority_queue<vector<int>, less<int> > pq1;     // 使用递增less<int>函数对象排序
priority_queue<deque<int>, greater<int> > pq2;   // 使用递减greater<int>函数对象排序
其成员函数有“判空(empty)” 、“尺寸(Size)” 、“栈顶元素(top)” 、“压栈(push)” 、“弹栈(pop)”等。


基本操作:

empty()      如果队列为空,则返回真

pop()    删除对顶元素,删除第一个元素

push()        加入一个元素

size()      返回优先队列中拥有的元素个数

top()     返回优先队列对顶元素,返回优先队列中有最高优先级的元素
#include <iostream>
#include <cstdio>
#include <queue> 
using namespace std;
struct Item{
	int num;//指令的序号
	int period;//指令的执行周期
	int time;//指令的下一次执行时间
 
	bool operator<(const Item& b)const{
		if(time != b.time){
			return time > b.time;
		}
 
		return num > b.num;
	}
};
 
 
int main()
{
	char s[20];
	priority_queue<Item> pq;
	while(scanf("%s",&s),s[0] != '#'){
		Item item;
		scanf("%d%d",&item.num,&item.period);
		item.time=item.period;
		pq.push(item);
	}
	int k;
	scanf("%d",&k);
	while(k--){//核心逻辑
		Item r=pq.top();//不断的取出来然后不断的插进去
		pq.pop();
		printf("%d\n",r.num);
		r.time+=r.period;
		pq.push(r);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37748451/article/details/86605398