UVALive 6093 Emergency Room --优先队列实现的模拟

题意:给n个医生,这些医生有一个上班时间,然后给一些病人,病人有一个到达的时间,以及一些诊断,诊断有property(优先级)和duration(诊断时间)这两个属性,每个病人可能要诊断多次,最后问每个病人的全部疗程完成离开医院的时间是多少。

分析:用优先队列存储诊断,病人,然后模拟一个诊断过程,完成病人的个数等于病人数的时候就结束。具体看代码吧。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstdlib>
using namespace std;
#define N 100102
#define M 22

struct treat
{
    int tim,ind;
    treat(int _tim,int _ind):tim(_tim),ind(_ind){}
    treat(){}
    bool operator <(const treat& a)const
    {
        return tim > a.tim;
    }
};

struct node
{
    int x,y;
    node(int _x,int _y):x(_x),y(_y){}
    node(){}
};

struct Patient
{
    int id,pro,arrtim;
    Patient(int _id,int _pro,int _arrtim):id(_id),pro(_pro),arrtim(_arrtim){}
    Patient(){}
    bool operator <(const Patient& a)const
    {
        if(a.pro == pro)
            return arrtim > a.arrtim;
        return pro < a.pro;
    }
};

priority_queue<treat> T;
priority_queue<Patient> P;
vector<node> pat[506],ans;
int arrive[506],treated[506];

int cmp(node ka,node kb)
{
    if(ka.x == kb.x)
        return ka.y < kb.y;
    return ka.x < kb.x;
}

int main()
{
    int n,Tim,a,b,Pcnt,cs = 1;
    int i,j;
    while(scanf("%d%d",&n,&Tim)!=EOF && (n+Tim))
    {
        Pcnt = 0;
        ans.clear();
        while(scanf("%d",&arrive[Pcnt]) && arrive[Pcnt] != -1)
        {
            pat[Pcnt].clear();
            while(scanf("%d%d",&a,&b) && (a+b))  //property,duration
                pat[Pcnt].push_back(node(a,b));
            Pcnt++;
        }
        while(!T.empty())
            T.pop();
        while(!P.empty())
            P.pop();
        for(i=0;i<n;i++)   //n个医生准备
            T.push(treat(Tim,-1));
        for(i=0;i<Pcnt;i++)
            T.push(treat(arrive[i],i)); //编号i
        int doctor = 0;
        memset(treated,-1,sizeof(treated));
        int pcnt = 0;
        while(pcnt < Pcnt)
        {
            int nowt = T.top().tim;
            while(!T.empty() && T.top().tim == nowt)
            {
                if(T.top().ind == -1)  //空闲doctor
                    doctor++;
                else
                {
                    int pid = T.top().ind;
                    treated[pid]++;
                    if(treated[pid] >= pat[pid].size()) //全部疗程完成
                    {
                        ans.push_back(node(nowt,arrive[pid]));
                        pcnt++;
                    }
                    else
                        P.push(Patient(pid,pat[pid][treated[pid]].x,arrive[pid]));
                }
                T.pop();
            }
            while(!P.empty() && doctor)
            {
                int k = P.top().id;
                T.push(treat(nowt+pat[k][treated[k]].y,-1)); //此时空闲
                T.push(treat(nowt+pat[k][treated[k]].y,k)); //或者继续诊断此病人
                P.pop();
                doctor--;
            }
        }
        sort(ans.begin(),ans.end(),cmp);
        printf("Case %d:\n",cs++);
        for(i=0;i<ans.size();i++)
            printf("Patient %d released at clock = %d\n",ans[i].y,ans[i].x);
    }
    return 0;
}

UVALive 6093 Emergency Room --优先队列实现的模拟,布布扣,bubuko.com

时间: 2024-08-06 20:08:46

UVALive 6093 Emergency Room --优先队列实现的模拟的相关文章

UVALive - 3135 - Argus (优先队列!!)

UVALive - 3135 Argus Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description A data stream is a real-time, continuous, ordered sequence of items. Some examples include sensor data, Internet traffic, financi

uva11997 K Smallest Sums&amp;&amp;UVALive 3135 Argus(优先队列,多路归并)

#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm> #include<stack> #in

UVALive 2323 Modular Multiplication of Polynomials(模拟)

这是一个相对简单的模拟,因为运算规则已经告诉了我们,并且比较简单,不要被吓到…… 思路:多项式除以另外一个多项式,如果能除,那么他的最高次一定被降低了,如果最高次不能被降低,那说明已经无法被除,就是题目要求输出的膜了,降低最高次的方法很简单,只要被除式的最高次 >= 除式的最高次,就将除式的最高次升高到与被除式一样高,然后让被除式减去它,直到不满足上述关系为止. 代码如下: #include<cstdio> #include<algorithm> #include<io

HDU 5818 Joint Stacks ——(栈的操作模拟,优先队列)

题意:有两个栈A和B,有3种操作:push,pop,merge.前两种都是栈的操作,最后一种表示的是如果“merge A B”,那么把B中的元素全部放到A中,且满足先入后出的栈原则. 分析:显然,我们给每一个节点配备一个时间戳即可.我一开始的思路是直接开两个优先队列进行直接模拟,merge操作就是把一个栈的元素全部倾倒到另一个栈内,但是会出现的问题是,如果有一个状态A和B的元素都相当多了,并且反复的进行merge操作,那么每一次merge都意味着大量的元素进出,肯定会超时的.因此,我们需要优化,

12100 Printer Queue(优先队列)

12100 Printer Queue12 The only printer in the computer science students’ union is experiencing an extremely heavy workload. Sometimes there are a hundred jobs in the printer queue and you may have to wait for hours to get a single page of output. Bec

POJ 3784 Running Median (最大最小堆)

最大最小堆动态求中位数 题意:输入M个数,当已输入的个数为奇数个时输出此时的中位数. 一共有M/2+1个中位数要输出,每一行10个. 分析: 用两个优先队列来模拟最大最小堆.中位数是x,就是有一半数比x小,一半数比x大. 刚好符合堆的特点. 用一个从大到小排序的优先队列q1来模拟小于x的数. 从小到大排序的优先队列q2来模拟大于x的数. 动态维护两个优先队列的元素个数.q1.size()=q2.size() 输入的数为偶数个时, q1.size()=q2.size()+1 输入的数为奇数个时.

2015长春网络赛总结

早上七点多就(冻)醒来了,训练了一个暑假,acm生涯的第一场网络赛,很激动. 九点开打,我拔不出网线,用的机房电脑,装的cb有问题,不能编译,只好用dev.男神电脑插上网线没有网,习惯了linux可能不习惯吧.这提醒我们以后一定要早点去把环境调好. 第三分钟,G题有人A了.我跟560开始看题,男神还在弄电脑.题意是给你n个数(n<1000),然后q(q<1000)次询问,要求你输出[l,r]区间的最大值.数据很小,我说暴力,然后560说线段树,然后模板13分钟1Y.然后560开始搞J,一个貌似

数据结构 编程实战 汇总———数据结构与算法分析第二版(C)

优先队列实现事件模拟 :http://maozj.iteye.com/blog/676567 d堆 左式堆 斜堆: http://blog.csdn.net/yangtrees/article/details/8252760 二项队列:http://www.cnblogs.com/xing901022/archive/2012/09/23/2699130.html (C++) http://blog.csdn.net/changyuanchn/article/details/14648463 (

Alisha’s Party---hdu5437(模拟+优先队列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5437 题意:公主有k个朋友来参加她的生日party,每个人都会带价值为v[i]的礼物过来,在所有人到齐之前公主会打开大门m次,每次开门就是在第t个人到来之后,然后让p个人进入大厅,如果当前人数不足p人,则让所有人都进去,最后在所有人都来到门口时,再次打开门,让剩下所有的人都进入大厅:当然选择礼物价值大的先进入,如果两个人的礼物价值相等,则先来的先进,现在有q个问题,问第ni个进入大厅的人是谁: 我们