洛谷-优先队列模拟-P2278 [HNOI2003]操作系统

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;
}
原文地址:https://www.cnblogs.com/tldr/p/11248888.html