紫书第五章习题 5-16 UVa 212 - Use of Hospital Facilities

出处:https://blog.csdn.net/xienaoban/article/details/52895020

题目链接:https://vjudge.net/contest/231030#problem/P

题意:模拟患者做手术。 
其条件为:医院有Nop个手术室、准备手术室要Mop分钟,另有Nre个恢复用的床、准备每张床要Mre分钟,早上Ts点整医院开张,从手术室手术完毕转移到回复床要Mtr分钟。现在医院早上开张了,给你一张患者的表,有Npa个患者等着做手术,每个患者的的信息有:名字、做手术需要的时间、恢复需要的时间。只要有空的手术室位就安排患者进去,优先安排门牌号低的。若多人同时竞争,输入列表靠前的先进。进入恢复室的优先顺序是,也是优先安排床号靠前的床,同时做完手术的人按照手术室的门牌号小的 (很奇葩的设定)优先。


//UVa212 - Use of Hospital Facilities
//Accepted 0.000s
//#define _XIENAOBAN_
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<utility>
#include<string>
#include<vector>
#include<queue>
#define ipt cin
#define opt cout//just for convenience and appearance, because size("cout"+" ")=5, which is longer than a tab(which is 4)
#define time_convert(t) setw(2) << (t / 60) << ':' << setfill('0') << setw(2) << (t % 60) << setfill(' ')
using namespace std;

struct ROOM {
    int id, at;
    ROOM() {}
    ROOM(int a, int b) :id(a), at(b) {}
    bool operator <(const ROOM& that) const {
        if (at != that.at) return at > that.at;
        return id > that.id;
    }
};
struct PATIENT {
    string name;
    int id, room, bed, top, tre, t1, t2, t3, t4;
};

int Nop, Nre, Ts, Te, Mtr, Mop, Mre, Npa;


int main()
{
#ifdef _XIENAOBAN_
#define gets(T) gets_s(T, 66666)
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif

    ios::sync_with_stdio(false);
    while (ipt >> Nop) {
        ipt >> Nre >> Ts >> Mtr >> Mop >> Mre >> Npa;
        Te = 0, Ts *= 60;
        vector<int> Top(Nop + 1, 0), Tre(Nre + 1, 0);
        vector<PATIENT> Info(Npa + 1);
        vector<int> Bre(Nre + 1, Ts);
        priority_queue<ROOM> Rop;
        for (int i(1);i <= Nop;++i) Rop.push(ROOM(i, Ts));

        //For all the operating rooms
        for (int N(1);N <= Npa;++N) {
            auto& now(Info[N]);
            now.id = N;
            ROOM op(Rop.top());
            Rop.pop();
            ipt >> now.name >> now.top >> now.tre;
            now.t1 = op.at;
            now.t2 = now.t1 + now.top;
            now.t3 = now.t2 + Mtr;
            now.t4 = now.t3 + now.tre;
            now.room = op.id;
            op.at = now.t2 + Mop;
            Top[op.id] += now.top;
            Rop.push(op);
        }
        sort(Info.begin() + 1, Info.end(), [](PATIENT& a, PATIENT& b)->bool
        {if (a.t2 != b.t2) return a.t2 < b.t2;return a.room < b.room;});//Sort by t2

        //For all the recovery rooms
        for (int N(1);N <= Npa;++N) {
            auto& now(Info[N]);
            int re;
            for (re = 1;re <= Nre;++re)
                if (Bre[re] <= now.t2) break;
            now.bed = re;
            Bre[re] = now.t4 + Mre;
            Tre[re] += now.tre;
            if (Te < now.t4) Te = now.t4;
        }
        sort(Info.begin() + 1, Info.end(), [](PATIENT& a, PATIENT& b) {return a.id < b.id;});//Sort by id

        //Output
        opt << " Patient          Operating Room          Recovery Room\n"
            << " #  Name     Room#  Begin   End      Bed#  Begin    End\n"
            << " ------------------------------------------------------\n";
        for (int N(1);N <= Npa;++N) {
            auto& now(Info[N]);
            opt << setw(2) << N << "  " << left << setw(10) << now.name << right << setw(2)
                << now.room << "   " << time_convert(now.t1) << "   " << time_convert(now.t2) << "     " << setw(2)
                << now.bed << "   " << time_convert(now.t3) << "   " << time_convert(now.t4) << '\n';
        }
        opt << '\n'
            << "Facility Utilization\n"
            << "Type  # Minutes  % Used\n"
            << "-------------------------\n";
        for (int N(1);N <= Nop;++N) {
            opt << "Room " << setw(2) << N << setw(8) << Top[N]
                << setw(8) << fixed << setprecision(2) << (Top[N] * 100.0 / (float)(Te - Ts)) << '\n';
        }
        for (int N(1);N <= Nre;++N) {
            opt << "Bed  " << setw(2) << N << setw(8) << Tre[N]
                << setw(8) << fixed << setprecision(2) << (Tre[N] * 100.0 / (float)(Te - Ts)) << '\n';
        }
        cout << endl;
    }
    return 0;
}
附:测试数据 
10 30 01 16 15 1 30 
Jones 
90 140 
Smith 
10 200 
Thompson 
60 75 
Albright 
40 82 
Poucher 
33 209 
Comer 
10 201 
Perry 
3 188 
Page 
111 120 
Roggio 
69 100 
Brigham 
42 79 
Nute 
22 71 
Young 
38 50 
Bush 
26 40 
Cates 
120 32 
Johnson 
10 2 
Jones 
28 140 
Smith 
120 200 
Thompson 
23 75 
Albright 
19 82 
Poucher 
133 209 
Comer 
74 101 
Perry 
93 188 
Page 
111 223 
Roggio 
69 122 
Brigham 
42 79 
Nute 
22 71 
Young 
38 140 
Bush 
26 121 
Cates 
120 248 
Johnson 
10 50

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值