洛谷-优先队列模拟-P2278 [HNOI2003]操作系统
基本思路
使用优先队列毋庸置疑,每次新来一个进程判断\(start>=now+q.top().run\),若大于,则队列头元素可在新元素到达前完成,直接到达完成状态即可;
若小于,且优先级不大于头元素,则插入队列;若优先级大于头元素,则需要中断,判断\(start-now\)即为队列头元素还可运行的时间,改变头元素的属性即可,然后插入新元素,头元素排队。
注意队列存放指向进程的id号,因此进程数组中课修改信息,优先队列元素为只读无法修改
已过hack,不开O2,第一次测评姬卡了居然给我test10给我超了10ms 233333.
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define FOR2(i,a,b) for(int i=a;i<=b;i++)
#define sync ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
#define MAXN 1000100
using namespace std;
typedef struct{
ll id,start,run,p;
}NODE;NODE nodes[MAXN];
struct cmp{
bool operator () (ll a,ll b)
{
if(nodes[a].p==nodes[b].p)return a>b;
return nodes[a].p<nodes[b].p;
}
};
priority_queue<ll,vector<ll>,cmp> q;
int main()
{//AC
ll id,start,run,p,now=0;
while(~scanf("%lld %lld %lld %lld",&id,&start,&run,&p))
{
if(now==0)now=start;
nodes[id]={id,start,run,p};
if(q.empty())
{
q.push(id);continue;
}
while(!q.empty()&&(now+nodes[q.top()].run)<=start)
{
now+=nodes[q.top()].run;
cout<<q.top()<<" "<<now<<endl;
q.pop();
}
ll diff=start-now;nodes[q.top()].run-=diff;
now=start;
q.push(id);
}
while(!q.empty())
{
now+=nodes[q.top()].run;
cout<<q.top()<<" "<<now<<endl;
q.pop();
}
return 0;
}