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