一道模拟题
竟然活生生的不会模拟,感觉自己好菜啊。
在模拟的时候,一定要弄清楚要对什么进行模拟。
题解
进程的等待队列是一个优先队列,优先队列是以优先级降序作为第一关键字,以进入时间为第二关键字。
在操作系统这道题目中,我们依据任务到达来驱动我们对进程的执行模拟。
记录上个任务到来的时间为now,本次任务到来的时间为tim。
(即上次中断的时间和本次中断的时间,是进程能够执行的时间)
这样的话,本次任务到达的时候,我们必须把等待队列中的任务拿出来,在
[now,tim)
[
n
o
w
,
t
i
m
)
这段时间内执行。如果有执行完的任务,那么就输出,否则的话,把剩余时长减去本次运行的时长,然后再push回等待队列中去。
并且把本次的任务推入到等待队列中去。
这样一直模拟下去就ok了。
本质上来说,任务的到来相当于一次中断,迫使所有的任务重新加回到优先队列里面去,然后把刚到来的任务也一同加入到优先队列去,重新选择一个优先级更高的执行。
代码
// luogu-judger-enable-o2
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
#define pr(x) cout<<#x<<":"<<x<<endl
struct job{
int pid,time,leng,prio;
};
struct cmp1{
bool operator()(job jb1,job jb2){
if(jb1.prio != jb2.prio) return jb1.prio < jb2.prio;
else return jb1.time > jb2.time;
}
};
int pid,tim,leng,prio,cnt,now,k;
int main(){
priority_queue<job,vector<job>,cmp1> Q;
while(k = scanf("%d%d%d%d",&pid,&tim,&leng,&prio)){
if(k == EOF) tim = 1e9;
job newjob = (job){pid,tim,leng,prio};
while(!Q.empty() && now < tim){
job tmp = Q.top();Q.pop();
int use = min(tim-max(now,tmp.time),tmp.leng);
tmp.leng -= use;
now = max(now,tmp.time)+use;
if(tmp.leng){
Q.push(tmp);
}
else{
printf("%d %d\n",tmp.pid,now);
}
}
Q.push(newjob);
if(k == EOF) break;
}
}