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

一道大模拟

题面想必大家都很清楚了,一堆进程在抢占资源,除了先来后到的顺序以外,优先级大的还可以插队,空闲的时候未结束的进程会插进来占用空闲的时间。

那么,我们可以容易地想到,我们寻找这个最大的优先级需要使用堆。

这里就要涉及到一个堆的比较。如果我们选用了STL,那么我们需要处理繁杂的比较关系。要用到运算符的重载…

struct Name{
   int data1,data2,data3;
   bool operator < (const Name &y) const{
      return this->data3 < y.data3;
   }
   bool operator > (const Name &y) const{
      return this->data3 > y.data3;
   }
};

没错就是这样的,上面这个结构体可以按data3比较。

那么放代码~

代码里的注释要看哦

#include <cstdio>
#include <queue>
inline int min(const int &a,const int &b) {
	return a<b? a:b;
}
//&取地址直接运算,既节省空间又节约了时间
//加上一个const保证不能修改
//绝对保险
struct task {
	int k,time,y;
	bool operator<(const task &x)const {
	    if(y==x.y) return k>x.k;
	     return y<x.y;
	}
    //这里也用到了const ... & ...
	bool operator>(const task &x)const {
	    if(y==x.y) return k<x.k;
		  return y>x.y;  //运算符重载
          //注意这里还要比较优先级相等时序号优先比较
          //成员函数,this指针在这里可以省略
	}
} now;
std::priority_queue <task> q;
//默认是大根堆,刚好符合我们的需求,缺省填写即可
//小跟堆是这样的std::priority_queue <int,vector<int>,greater<int> > qq;
//当然没用
int main() {
	int a,b,c,k,tim=0;  //tim是时间节点

	while(scanf("%d%d%d%d",&k,&a,&b,&c)!=EOF) {
		while(tim<a) {
        //now是用来记录正在跑的进程,相当于一个Cpu
        //now.k=0的意思是当前CPU处于空闲状态
        //空闲时间要利用起来跑进程
			int tmp=min(now.time,a-tim);
         //这里可以避免最后一次跑不完的情况
			tim+=tmp,now.time-=tmp;
			if(now.time==0) {
         //如果进程时间跑完了
				if(now.k) printf("%d %d\n",now.k,tim);
				if(!q.empty()) now=q.top(),q.pop();
				else {
             //如果队列已空说明没有进程可以跑了,直接跑下一个
             //有上now.k=0的意思是当前CPU处于空闲状态
             //所以now.k=0
					now.k=0;
					break;
				}

			} else break;
        //空闲时间用完了也要退出
		}
		if(tim<a) tim=a;
     //其实这行可以和上面那个队列已空的合并成一句
		if(c>now.y||!now.k) {
			if(now.k) q.push(now);
			now=(task) { k,b,c };
        //插进来一个优先级大的(或者CPU空闲)
		} else {
			task tmp;
			tmp.k=k,tmp.time=b,tmp.y=c;
			q.push(tmp);
        //否则讲究先来后到
		}
	}
	while(!q.empty()) {
     //还有没做完的进程啊,还要按优先级跑进程
		tim+=now.time;
		now.time-=now.time;
		printf("%d %d\n",now.k,tim);
		now=q.top();
		q.pop();
	}
   //弹完之后多出了最后一块
	tim+=now.time;
	now.time-=now.time;
	printf("%d %d\n",now.k,tim);
   //很不美观...
	return 0;
}

完结撒花~

posted @ 2022-06-28 21:30  Reiss  阅读(28)  评论(0编辑  收藏  举报