P2278 [HNOI2003]操作系统
时间:2021-07-25
本文章向大家介绍P2278 [HNOI2003]操作系统,主要包括P2278 [HNOI2003]操作系统使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
[HNOI2003]操作系统
题目描述
写一个程序来模拟操作系统的进程调度。假设该系统只有一个CPU,每一个进程的到达时间,执行时间和运行优先级都是已知的。其中运行优先级用自然数表示,数字越大,则优先级越高。 如果一个进程到达的时候CPU是空闲的,则它会一直占用CPU直到该进程结束。除非在这个过程中,有一个比它优先级高的进程要运行。在这种情况下,这个新的(优先级更高的)进程会占用CPU,而老的只有等待。 如果一个进程到达时,CPU正在处理一个比它优先级高或优先级相同的进程,则这个(新到达的)进程必须等待。 一旦CPU空闲,如果此时有进程在等待,则选择优先级最高的先运行。如果有多个优先级最高的进程,则选择到达时间最早的。
输入输出格式
输入格式
输入包含若干行,每一行有四个自然数(均不超过10^8),分别是进程号,到达时间,执行时间和优先级。不同进程有不同的编号,不会有两个相同优先级的进程同时到达。输入数据已经按到达时间从小到大排序。输入数据保证在任何时候,等待队列中的进程不超过15000个。
输出格式
按照进程结束的时间输出每个进程的进程号和结束时间。
输入输出样例
输入样例 #1
1 1 5 3 2 10 5 1 3 12 7 2 4 20 2 3 5 21 9 4 6 22 2 4 7 23 5 2 8 24 2 4
输出样例 #1
1 6 3 19 5 30 6 32 8 34 4 35 7 40 2 42
不难想到用堆去维护已经到达的进程的运行顺序,用set维护一个时间戳,将所有进程按到达时间排序,依次压入优先队列(纯粹是花里胡哨,本来可以一边读入一边压入的,加了一个set麻烦还不好调试)
当队列中只有一个进程时, 它将独自占用CPU, 直接计算它花费的时间并把下一个进程压入队列
否则就按照优先级和到达时间排序,优先运行优先级最大,到达时间最早的进程
当一个进程还没运行完,下一进程又到了时,从这个进程的运行时间中减去间隔时间,然后把两个进程重新入队
#include <cstdio>
#include <set>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define int long long
const int N = 1e5 + 120;
struct node
{
int pid;
int arrive_time;
int routine_time;
int priority;
bool operator<(const node a) const
{
if (priority != a.priority)
return priority < a.priority;
else
return arrive_time > a.arrive_time;
}
};
struct node2
{
int pid;
int arrive_time;
int routine_time;
int priority;
bool operator<(const node2 a) const
{
if (arrive_time != a.arrive_time)
return arrive_time < a.arrive_time;
else
return priority > a.priority;
}
} t[N];
int n;
priority_queue q;
set s;
int a, b, c, d;
signed main()
{
// freopen("HO.in", "r", stdin);
// freopen("HO.out", "w", stdout);
while (~scanf("%lld %lld %lld %lld", &a, &b, &c, &d))
{
s.insert((node2){a, b, c, d});
//printf("insert %lld %lld %lld %lld\n", a, b, c, d);
}
node2 t = *s.begin();
q.push((node){t.pid, t.arrive_time, t.routine_time, t.priority});
auto it = s.begin();
it++;
int timestamp = q.top().arrive_time;
while (q.size())
{
node f = q.top();
q.pop();
//printf("routine %lld pri %lld timeleft %lld\n", f.pid,f.priority ,f.routine_time);
int res;
int arrive;
if(it != s.end()) arrive = (*it).arrive_time;
else arrive = 1e9;
if (f.routine_time + timestamp <= arrive || it == s.end())
{
timestamp += f.routine_time;
printf("%lld %lld\n", f.pid, timestamp);
if (!q.size())
{
timestamp = (*it).arrive_time;
if (it != s.end())
{
node2 t = *it;
q.push((node){t.pid, t.arrive_time, t.routine_time, t.priority});
it++;
}
}
}
else
{
res = (*it).arrive_time - timestamp;
f.routine_time -= res;
timestamp = (*it).arrive_time;
//printf("task %lld has arrived task %lld waiting routine_time last %lld\n",(*it).pid, f.pid, f.routine_time);
q.push(f);
if (it != s.end())
{
node2 t = *it;
q.push((node){t.pid, t.arrive_time, t.routine_time, t.priority});
it++;
}
}
}
return 0;
}
原文地址:https://www.cnblogs.com/lyc-lb-blogs/p/15057366.html
- fasthttp中的协程池实现
- Oracle 12c R2版本 Application Containers 特性(二)
- go sync.Mutex 设计思想与演化过程 --转
- hadoop开发必读:认识Context类的作用
- Logback+ELK+SpringMVC搭建日志收集服务器
- 【译】Spring 官方教程:创建批处理服务
- Oracle12c R2版本Application Containers特性(三)
- Shell系列-编写及执行脚本
- Spring Security 入门(五):在 Spring-Boot中的应用
- Go语言Goroutine与Channel内存模型
- Tarjan--LCA算法的个人理解即模板
- spark sql编程之实现合并Parquet格式的DataFrame的schema
- Oracle压缩黑科技(一)—基础表压缩
- 12 条用于 Linux 的 MySQL/MariaDB 安全最佳实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android 自定义View实现多节点进度条功能
- android studio无法添加 bmob sdk依赖问题及解决方法
- Android自定义ToolBar并实现沉浸式的方法
- python初学者笔记—入门基础知识
- Android SurfaceView画板操作
- Android利用Andserver搭建服务器的详细教程
- 位运算处理进制转换问题
- python的to_sql那点儿事
- Android自定义控件之刻度尺控件
- Android 使用Vibrator服务实现点击按钮带有震动效果
- sprintf函数的使用
- Android实现定时任务及闹钟
- Android使用ftp方式实现文件上传和下载功能
- slenium模拟登陆知乎2020
- Android两种轮询的实现方法