紫书5-16UVa212

在这里插入图片描述构造事件队列,依次处理即可。
注意:如果两人同时做完手术,则手术室序号小的人优先进入恢复室

#include<bits/stdc++.h>
using namespace std;
struct Event{
    int time,id,type;
    Event(int t,int id,int type):time(t),id(id),type(type){}
    bool operator<(const Event&e)const {return time>e.time;}
};
enum eventType{
    opFree=0,opPre=1,reFree=3,rePre=4
};
struct Room
{
    int pat,minutes;
    void init(){pat=-1;minutes=0;}
};
struct Patient{
    string name;
    int surgeryTime,recoveryTime,opRoomId,opBeginTime,opEndTime,reRoomId,reBeginTime,reEndTIme;
};
priority_queue<Event>em;
int nOp,nRe,T0,tTrans,tPreOp,tPreRe,nPat,allTime;
Room opRooms[10+1],reRooms[30+1];
Patient pats[100+1];
struct patComp
{
    bool operator()(int i1,int i2)
    {
        const Patient& p1=pats[i1];
        const Patient&p2=pats[i2];
        assert(p1.opRoomId!=-1&&p2.opRoomId!=-1);
        return p1.opRoomId<p2.opRoomId;
    }
};
set<int>opQueue,freeOpRooms,freeReRooms;
set<int,patComp>reQueue;
typedef set<int>::iterator siit;
void writeTime(char*buf,int time){
    int h=time/60+T0,m=time%60;
    sprintf(buf,"%2d:%02d",h,m);
}
ostream&operator<<(ostream&os,const Patient& p)
{
    char buf[18];
    sprintf(buf,"  %-10s%2d   ",p.name.c_str(),p.opRoomId+1);os<<buf;
    writeTime(buf,p.opBeginTime); os<<buf<<"   ";
    writeTime(buf,p.opEndTime);os<<buf;
    sprintf(buf,"%7d",p.reRoomId+1);os<<buf<<"   ";
    writeTime(buf,p.reBeginTime);os<<buf<<"   ";
    writeTime(buf,p.reEndTIme);os<<buf;
    return os;
}
ostream& operator<<(ostream&os,const Room&r)
{
    double p=r.minutes*100;
    p/=allTime;
    char buf[64];
    sprintf(buf,"%8d  %6.2lf",r.minutes,p);
    return os<<buf;
}
void solve(){
    int time=em.top().time;
    
    while(!em.empty()&&em.top().time==time)
    {
        Event e=em.top();
        em.pop();
        int pid;
        switch(e.type)
        {
            case opFree:
                assert(!freeOpRooms.count(e.id));
                freeOpRooms.insert(e.id);
                assert(opRooms[e.id].pat==-1);
                break;
            case opPre:
                assert(!freeOpRooms.count(e.id));
                pid=opRooms[e.id].pat;
                assert(pid!=-1);
                reQueue.insert(pid);
                opRooms[e.id].pat=-1;
                em.push(Event(time+tPreOp,e.id,opFree));
                break;
            case reFree:
                assert(!freeReRooms.count(e.id));
                assert(reRooms[e.id].pat==-1);
                freeReRooms.insert(e.id);
                break;
            case rePre:
                assert(!freeReRooms.count(e.id));
                assert(reRooms[e.id].pat!=-1);
                reRooms[e.id].pat=-1;
                em.push(Event(time+tPreRe,e.id,reFree));
                break;
            default:
                assert(false);
        }
    }
    int opSz=min(opQueue.size(),freeOpRooms.size());
    for(int i=0;i<opSz;++i)
    {
        int pid=*(opQueue.begin());
        opQueue.erase(opQueue.begin());
        int rid=*(freeOpRooms.begin());
        freeOpRooms.erase(freeOpRooms.begin());
        Room&r =opRooms[rid];
        r.pat=pid;
        Patient&p=pats[pid];
        p.opRoomId=rid;
        p.opBeginTime=time;
        p.opEndTime=time+p.surgeryTime;
        r.minutes+=p.surgeryTime;
        em.push(Event(p.opEndTime,rid,opPre));

    }
    int reSz=min(reQueue.size(),freeReRooms.size());
    for(int i=0;i<reSz;++i)
    {
        int pid=*(reQueue.begin());reQueue.erase(reQueue.begin());
        int rid=*(freeReRooms.begin());freeReRooms.erase(freeReRooms.begin());
        Room&r=reRooms[rid];
        r.pat=pid;
        Patient&p=pats[pid];
        p.reRoomId=rid;
        p.reBeginTime=time+tTrans;
        p.reEndTIme=p.reBeginTime+p.recoveryTime;
        r.minutes+=p.recoveryTime;
        em.push(Event(p.reEndTIme,rid,rePre));
        allTime=max(allTime,p.reEndTIme);
    }
}
int main()
{
    //freopen("../input.txt","r",stdin);
    //freopen("../output.txt","w",stdout);
    while(cin>>nOp)
    {
        assert(opQueue.empty());
        assert(reQueue.empty());
        assert(em.empty());
        freeOpRooms.clear();
        freeReRooms.clear();
        allTime=0;
        cin>>nRe>>T0>>tTrans>>tPreOp>>tPreRe>>nPat;
        for(int i=0;i<nOp;++i)
        {
            em.push(Event(0,i,opFree));
            opRooms[i].init();
        }
        for(int i=0;i<nRe;++i)
        {
            em.push(Event(0,i,reFree));
            reRooms[i].init();
        }
        for(int i=0;i<nPat;++i)
        {
            Patient&p=pats[i];
            p.opRoomId=-1;
            p.reRoomId=-1;
            cin>>p.name>>p.surgeryTime>>p.recoveryTime;
            opQueue.insert(i);
        }
        while(!em.empty())
        {
            solve();
        }
        cout<<" Patient          Operating Room          Recovery Room\n";
        cout<<" #  Name     Room#  Begin   End      Bed#  Begin    End\n";
        cout<<" ------------------------------------------------------\n";
        for(int i=0;i<nPat;++i)
            cout<<setw(2)<<i+1<<pats[i]<<endl;
        cout<<endl;
        cout<<"Facility Utilization"<<endl;
        cout<<"Type  # Minutes  % Used\n";
        cout<<"-------------------------\n";
        for(int i=0;i<nOp;++i)cout<<"Room "<<setw(2)<<i+1<<opRooms[i]<<endl;
        for(int i=0;i<nRe;++i)cout<<"Bed  "<<setw(2)<<i+1<<reRooms[i]<<endl;
        cout<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的程序

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值