发布于 

Luogu 2278

Luogu 2278

好久以前就做了一次,没有做出来。这次又做了一遍,感觉思路清晰了不少。

题目来源: Luogu

分析

由题目可得,我们当前应当运行的进程应该主要取决于进程的优先级,其次取决于进程进入的时间。由于我们只需要知道优先级最高的程序,所以这明显是个堆,所以我们应该使用优先队列来完成。

实现步骤

我们首先维护一个当前的时间,然后有一个优先队列。

对于每一次的输入,我们都需要对优先队列进行update,从而将当前时间到此次输入开始的时间这个时间范围中能够运行完毕的进程进行输出,然后在有限队列中插入该进程。

在输入完所有进程后,依次将优先队列中的进程取出,其中应记得更新时间。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;

struct Point
{
trueint pid,st,last,rank;

truePoint(int pid=0,int st=0,int last=0,int rank=0):pid(pid),st(st),last(last),rank(rank) {}

truevoid Print(int t) //进程运行完毕时的输出
{
truetrueprintf("%d %d\n",pid,t);
true}

trueconst bool operator < (const Point& tmp)const{ //将rank高或者rank相等并且st早的进程排在前面
truetruereturn rank<tmp.rank || (rank==tmp.rank && st>tmp.st);
true}
};

priority_queue<Point> q;

int main()
{
trueint a,b,c,d;
trueint t = 0;
truewhile (scanf("%d%d%d%d",&a,&b,&c,&d)!=EOF) //这里一定要写!=EOF,否则可能超时
true{
truetruewhile ((!q.empty()) && q.top().last + t <= b)
truetrue{
truetruetruePoint p = q.top();
truetruetruet += p.last; //更改时间
truetruetruep.Print(t); //输出
truetruetrueq.pop(); //取出已经运行完毕的而进程
truetrue}
truetrueif (!q.empty()) //如果还有进程的话
truetrue{ //该进程可以运行一定时间,但是不能运行完毕
truetruetruePoint p = q.top(); q.pop();
truetruetruep.last -= b - t;
truetruetrueq.push(p);
truetrue}
truetruet = b; //调整时间

truetrueq.push(Point(a,b,c,d));
true}

truewhile (!q.empty()) //输出所有剩下的进程
true{
truetruePoint p = q.top();
truetruet += p.last;
truetruep.Print(t);
truetrue
truetrueq.pop();
true}
}

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 [@Songer](https://blog.songer.xyz/) 创建,使用 Stellar 作为主题。