题目

这个题是一个名副其实的考验细节和头脑清醒的一个题。

根据提议我们可以进行分类讨论。

我们用优先队列来模拟CPU,我们可以用在线的算法来写,每次输入一个进程都要判断这个进程是否可以挤掉优先队列里的进程,当可以挤掉时就可以换下一个进程了,我们可以把最大的挤掉,其余就都可以挤掉了,而如果该进程挤不掉,那就按照从优先级大到小的顺序输出结束时间和编号。

\(code\)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
struct cym {
int id, t, point;
}data[100100];
bool operator < (cym a, cym b)
{
if (a.point == b.point)
return a.id > b.id;//因为id和left是成正比的,所以我们可以用它来排序顺便节省空间。
return a.point < b.point;
}
priority_queue <cym> q;
//queue <cym> qweit;
int main()
{
int a, b, c, d, tot = 0, n, maxn = 0, time;
while (cin >> a)
{
scanf("%d%d%d", &b, &c, &d);
while (!q.empty())
{
cym cur = q.top(); q.pop();
if ((cur.t + time) <= b)
time += cur.t, printf("%d %d\n", cur.id, time);
else //if (d >= cur.point)// 注意这里不能加,因为加上会导致cur重新入队不了
{
cur.t -= b - time, q.push({cur.id, cur.t, cur.point}); //注意还要break,不然会死循环,或者说是当前的b已经入队,所以需要换一个b。
break;
}
}//因为无论队列空没空,都需要将当前时间更新到b,因为将当前top重新入队后优先级如果还是最高的这一步是不影响的,而如果不是最高的话那top就是{a,c,d}
q.push({a, c, d}); time = b;
}
while (!q.empty())
{
cym cur = q.top(); q.pop();
time += cur.t;
printf("%d %d\n", cur.id, time);
}
}
05-06 20:16