题解 P2278 【[HNOI2003]操作系统】

这道题可以直接使用优先队列来模拟,不过需要注意的是要想清楚执行的流程。

流程如下:

  1. 创建一个空的优先队列,把“当前运行的进程”和“当前时间”全部清零。
  2. 读入一个进程。若已读到文件结尾则创建一个虚拟的进程,其到达时间为无穷大,设这个进程为 p。
  3. 每次取出队中优先级最高的进程。若这样的进程有多个,则取出到达时间最早的进程。设为 q。
  4. 若“当前时间”到 p 的到达时间内足以运行 q,则运行 q,输出q的答案,返回3;否则运行 q 直到 p 到达为止,并将 q 扔回优先队列,继续执行5。
  5. 若p不是虚拟的,则将p加入优先队列。

以上为这个程序的大致流程。另外由于数据量比较大,建议不要用iostream,谨防TLE。

代码:

#include <bits/stdc++.h>
#define debug printf("Running %s on line %d...\n",__FUNCTION__,__LINE__)
#define in inline
#define re register
using namespace std;
typedef long long ll;
typedef double db;
in int read()
{
    int ans=0,f=1;char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;else if (c==EOF) return -1;
    for (;isdigit(c);c=getchar()) ans=(ans<<3)+(ans<<1)+(c^48);
    return ans*f;
}
in int cmin(int &a,int b) {return a=min(a,b);}
in int cmax(int &a,int b) {return a=max(a,b);}
struct data
{
    int id,st,t,pri;
    bool operator < (const data &rhs) const
    {
        return pri==rhs.pri?st>rhs.st:pri<rhs.pri;
    }
};
priority_queue<data> q;
data now,nul;
int lst;
int main()
{
    nul=now={0,0,0,0};
    while (true)
    {
        int id=read(),st,t,pri;
        if (id==-1) st=200000001,t=0,pri=0;
        else st=read(),t=read(),pri=read();
        while (!q.empty())
        {
            data p=q.top();q.pop();
            if (p.t<=st-lst)
            {
                lst+=p.t,now=nul;
                printf("%d %d\n",p.id,lst);
            }
            else p.t-=(st-lst),lst=st,now=p,q.push(p);
            if (lst==st) break;
        }
        if (id==-1) return 0;
        q.push({id,st,t,pri});
        lst=st;
    }
    return 0;
}