• UVA 212 Use of Hospital Facilities


    题目链接:https://vjudge.net/problem/UVA-212

    题意摘自《算法禁赛入门经典》

    题目大意

      医院里有 N(N ≤ 10)个手术室和 M(M ≤ 30)个恢复室。每个病人首先会被分配到一个手术室,手术后会被分配到一个恢复室。从任意手术室到任意恢复室的时间均为 t1,准备一个 手术室和恢复室的时间分别为 t2 和 t3 (一开始所有手术室和恢复室均准备好,只有接待完一个病人之后才需要为下一个病人准备)。
      K 名(K ≤ 100)病人按照花名册顺序排队,T 点钟准时开放手术室。每当有准备好的手术室时,队首病人进入其中编号最小的手术室。手术结束后,病人应立刻进入编号最小的恢复室。如果有多个病人同时结束手术,在编号较小的手术室做手术的病人优先进入编号较小的恢复室。输入保证病人无须排队等待恢复室。
      输入 N、M、T、t1、t2、t3、K 和 K 名病人的名字、手术时间和恢复时间,模拟这个过程。

    分析

      要点:
    1. 多组数据,数据之间空一行,每组数据表间空一行。
    2. 0 个病人的情况。
    3. 手术结束时间相同的,手术室编号小的先安排。
    4. 手术完成后应当立即选择恢复室并移动。

    代码如下

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3  
      4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
      5 #define Rep(i,n) for (int i = 0; i < (int)(n); ++i)
      6 #define For(i,s,t) for (int i = (int)(s); i <= (int)(t); ++i)
      7 #define rFor(i,t,s) for (int i = (int)(t); i >= (int)(s); --i)
      8 #define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
      9 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
     10 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
     11 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
     12  
     13 #define pr(x) cout << #x << " = " << x << "  "
     14 #define prln(x) cout << #x << " = " << x << endl
     15  
     16 #define LOWBIT(x) ((x)&(-x))
     17  
     18 #define ALL(x) x.begin(),x.end()
     19 #define INS(x) inserter(x,x.begin())
     20 #define UNIQUE(x) x.erase(unique(x.begin(), x.end()), x.end())
     21 #define REMOVE(x, c) x.erase(remove(x.begin(), x.end(), c), x.end()); // 删去 x 中所有 c 
     22 #define TOLOWER(x) transform(x.begin(), x.end(), x.begin(),::tolower);
     23 #define TOUPPER(x) transform(x.begin(), x.end(), x.begin(),::toupper);
     24  
     25 #define ms0(a) memset(a,0,sizeof(a))
     26 #define msI(a) memset(a,0x3f,sizeof(a))
     27 #define msM(a) memset(a,-1,sizeof(a))
     28 
     29 #define MP make_pair
     30 #define PB push_back
     31 #define ft first
     32 #define sd second
     33  
     34 template<typename T1, typename T2>
     35 istream &operator>>(istream &in, pair<T1, T2> &p) {
     36     in >> p.first >> p.second;
     37     return in;
     38 }
     39  
     40 template<typename T>
     41 istream &operator>>(istream &in, vector<T> &v) {
     42     for (auto &x: v)
     43         in >> x;
     44     return in;
     45 }
     46 
     47 template<typename T>
     48 ostream &operator<<(ostream &out, vector<T> &v) {
     49     Rep(i, v.size()) out << v[i] << " 
    "[i == v.size() - 1];
     50     return out;
     51 }
     52  
     53 template<typename T1, typename T2>
     54 ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
     55     out << "[" << p.first << ", " << p.second << "]" << "
    ";
     56     return out;
     57 }
     58 
     59 inline int gc(){
     60     static const int BUF = 1e7;
     61     static char buf[BUF], *bg = buf + BUF, *ed = bg;
     62     
     63     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
     64     return *bg++;
     65 } 
     66 
     67 inline int ri(){
     68     int x = 0, f = 1, c = gc();
     69     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
     70     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
     71     return x*f;
     72 }
     73 
     74 template<class T>
     75 inline string toString(T x) {
     76     ostringstream sout;
     77     sout << x;
     78     return sout.str();
     79 }
     80 
     81 inline int toInt(string s) {
     82     int v;
     83     istringstream sin(s);
     84     sin >> v;
     85     return v;
     86 }
     87 
     88 //min <= aim <= max
     89 template<typename T>
     90 inline bool BETWEEN(const T aim, const T min, const T max) {
     91     return min <= aim && aim <= max;
     92 }
     93 
     94 typedef unsigned int uI;
     95 typedef long long LL;
     96 typedef unsigned long long uLL;
     97 typedef vector< int > VI;
     98 typedef vector< bool > VB;
     99 typedef vector< char > VC;
    100 typedef vector< double > VD;
    101 typedef vector< string > VS;
    102 typedef vector< LL > VL;
    103 typedef vector< VI > VVI;
    104 typedef vector< VB > VVB;
    105 typedef vector< VS > VVS;
    106 typedef vector< VL > VVL;
    107 typedef vector< VVI > VVVI;
    108 typedef vector< VVL > VVVL;
    109 typedef pair< int, int > PII;
    110 typedef pair< LL, LL > PLL;
    111 typedef pair< int, string > PIS;
    112 typedef pair< string, int > PSI;
    113 typedef pair< string, string > PSS;
    114 typedef pair< double, double > PDD;
    115 typedef vector< PII > VPII;
    116 typedef vector< PLL > VPLL;
    117 typedef vector< VPII > VVPII;
    118 typedef vector< VPLL > VVPLL;
    119 typedef vector< VS > VVS;
    120 typedef map< int, int > MII;
    121 typedef unordered_map< int, int > uMII;
    122 typedef map< LL, LL > MLL;
    123 typedef map< string, int > MSI;
    124 typedef map< int, string > MIS;
    125 typedef multiset< int > mSI;
    126 typedef set< int > SI;
    127 typedef stack< int > SKI;
    128 typedef deque< int > DQI;
    129 typedef queue< int > QI;
    130 typedef priority_queue< int > PQIMax;
    131 typedef priority_queue< int, VI, greater< int > > PQIMin;
    132 const double EPS = 1e-8;
    133 const LL inf = 0x7fffffff;
    134 const LL infLL = 0x7fffffffffffffffLL;
    135 const LL mod = 1e9 + 7;
    136 const int maxN = 1e4 + 7;
    137 const LL ONE = 1;
    138 const LL evenBits = 0xaaaaaaaaaaaaaaaa;
    139 const LL oddBits = 0x5555555555555555;
    140 
    141 struct Time {
    142     int val = 0; // 总的分钟数 
    143     
    144     bool operator< (const Time &x) const {
    145         return val < x.val;
    146     }
    147     
    148     bool operator== (const Time &x) const {
    149         return val == x.val;
    150     }
    151     
    152     bool operator> (const Time &x) const {
    153         return val > x.val;
    154     }
    155     
    156     Time operator+ (const int &k) const {
    157         Time ret;
    158         ret.val = val + k;
    159         return ret;
    160     }
    161     
    162     Time operator+ (const Time &x) const {
    163         Time ret;
    164         ret.val = val + x.val;
    165         return ret;
    166     }
    167     
    168     string getString() {
    169         string ret;
    170         ret = toString(val / 60) + ":";
    171         if((val % 60) / 10 == 0) ret += "0";
    172         ret += toString(val % 60);
    173         return ret;
    174     }
    175 }; 
    176 
    177 struct Patient {
    178     int id;                     // 病人在,名册上的 id 
    179     string name;                 // 病人名字 
    180     int surgeryTime;            // 病人手术时间 
    181     int recoveryTime;            // 病人恢复时间 
    182     
    183     int surgeryRoomId;             // 所进行手术的手术室 id 
    184     Time surgeryBeginTime;        // 手术开始时间 
    185     Time surgeryEndTime;        // 手术结束时间 
    186     
    187     int recoveryRoomId;            // 所进行恢复的恢复室 id 
    188     Time recoveryBeginTime;        // 恢复开始时间 
    189     Time recoveryEndTime;        // 恢复结束时间 
    190     
    191     Patient(int x) : id(x) {} 
    192 }; 
    193 
    194 istream& operator >> (istream& in, Patient& x){
    195     in >> x.name >> x.surgeryTime >> x.recoveryTime;
    196     return in;
    197 }
    198 
    199 ostream& operator << (ostream& out, Patient& x){
    200     printf("%2d  %-8s  %2d   %5s   %5s     %2d   %5s   %5s", x.id, x.name.c_str(), x.surgeryRoomId, x.surgeryBeginTime.getString().c_str(), x.surgeryEndTime.getString().c_str(), x.recoveryRoomId, x.recoveryBeginTime.getString().c_str(), x.recoveryEndTime.getString().c_str()); 
    201     return out;
    202 }
    203 
    204 struct Facility {
    205     int id;                // 设施 id 
    206     string type;        // 设施类型 
    207     int timeUsed;        // 设施被使用的时间
    208     double usedPercent;    // 使用时间百分比 
    209     
    210     Facility(int x, string y) {
    211         id = x;
    212         type = y;
    213         timeUsed = 0;
    214         usedPercent = 0;
    215     } 
    216 }; 
    217 
    218 ostream& operator << (ostream& out, const Facility& x) {
    219     printf("%-4s %2d %7d  %6.2f", x.type.c_str(), x.id, x.timeUsed, x.usedPercent); 
    220     return out;
    221 }
    222 
    223 struct Event {
    224     // 1 代表患者可进行手术事件
    225     // 2 代表患者可进行恢复事件
    226     // 3 代表手术室空闲事件
    227     // 4 代表恢复室空闲事件
    228     int type;
    229     int idx; // 对应数组下表
    230     Time time; // 事件可进行时间
    231     
    232     Event(int x, int y, Time z) {
    233         type = x;
    234         idx = y;
    235         time = z;
    236     }
    237     
    238     bool operator< (const Event &x) const {
    239         return time > x.time || time == x.time && idx > x.idx;
    240     }
    241 };
    242 
    243 int N;                             // 手术室数量,小于等于 10
    244 vector< Facility > rooms;        // 手术室房间数组 
    245 int M;                             // 恢复室数量,小于等于 30
    246 vector< Facility > beds;        // 恢复室床数组 
    247 Time startTime;                 // 一天中医院的开始营业时间,整点,24小时格式 
    248 Time endTime;                    // 所有手术的结束时间 
    249 int totalTime;                    // 手术总持续时间 
    250 int tranTime;                     // 手术室转移恢复室时间(分钟) 
    251 int surgeryResetTime;            // 手术室准备时间(分钟) 
    252 int recoveryResetTime;             // 恢复室准备时间(分钟) 
    253 vector< Patient > roster;         // 病人名册
    254 int patientNum;                    // 病人人数 
    255 int tmp; 
    256 
    257 struct RoomCmp {
    258     bool operator() (int x, int y) {
    259         return rooms[x].id > rooms[y].id;
    260     }
    261 };
    262 
    263 struct BedCmp {
    264     bool operator() (int x, int y) {
    265         return beds[x].id > beds[y].id;
    266     }
    267 };
    268 
    269 struct RecoveryComp {
    270     bool operator() (int x, int y) {
    271         if(roster[x].surgeryEndTime == roster[y].surgeryEndTime) return roster[x].surgeryRoomId > roster[y].surgeryRoomId;
    272         return roster[x].surgeryEndTime > roster[y].surgeryEndTime;
    273     }
    274 };
    275 
    276 priority_queue< Event > Q;                          // 活动队列 
    277 QI surgeryQ;                                        // 等待手术队列 
    278 priority_queue< int, VI, RecoveryComp > recoveryQ;     // 等待恢复队列 
    279 priority_queue< int, VI, RoomCmp > roomQ;            // 手术室空闲队列 
    280 priority_queue< int, VI, BedCmp > bedQ;                // 恢复室空闲队列 
    281 
    282 void init() {
    283     rooms.clear();
    284     beds.clear();
    285     endTime = startTime;
    286     roster.clear();
    287     
    288     while(!Q.empty()) Q.pop();
    289     while(!surgeryQ.empty()) surgeryQ.pop();
    290     while(!recoveryQ.empty()) recoveryQ.pop();
    291     while(!roomQ.empty()) roomQ.pop();
    292     while(!bedQ.empty()) bedQ.pop();
    293 }                            
    294 
    295 bool readData() {
    296     if(!(cin >> N >> M >> tmp >> tranTime >> surgeryResetTime >> recoveryResetTime >> patientNum)) return false;
    297     startTime.val = tmp * 60;
    298     
    299     init();
    300     
    301     Rep(i, N) rooms.PB(Facility(i + 1, "Room"));
    302     Rep(i, M) beds.PB(Facility(i + 1, "Bed"));
    303     
    304     Rep(i, patientNum) {
    305         roster.PB(Patient(i + 1));
    306         cin >> roster[i];
    307     }
    308     
    309     return true;
    310 }
    311 
    312 void printSheet() {
    313     printf(" Patient          Operating Room          Recovery Room
    ");
    314     printf(" #  Name     Room#  Begin   End      Bed#  Begin    End
    ");
    315     printf(" ------------------------------------------------------
    ");
    316     Rep(i, patientNum) cout << roster[i] << endl;
    317     
    318     cout << endl;
    319     
    320     printf("Facility Utilization
    ");
    321     printf("Type  # Minutes  % Used
    ");
    322     printf("-------------------------
    ");
    323     Rep(i, N) {
    324         if(totalTime) rooms[i].usedPercent = 100.0 * rooms[i].timeUsed / totalTime;
    325         cout << rooms[i] << endl;
    326     }
    327     Rep(i, M) {
    328         if(totalTime) beds[i].usedPercent = 100.0 * beds[i].timeUsed / totalTime;
    329         cout << beds[i] << endl;
    330     }
    331 } 
    332 
    333 void solve() {
    334     Time nowTime;
    335     Rep(i, patientNum) Q.push(Event(1, i, startTime));
    336     Rep(i, N) Q.push(Event(3, i, startTime));
    337     Rep(i, M) Q.push(Event(4, i, startTime));
    338     
    339     while(!Q.empty()) {
    340         nowTime = Q.top().time;
    341         
    342         while(!Q.empty() && nowTime == Q.top().time) { // 把这个时间到到达的活动全取出来 
    343             Event e = Q.top(); Q.pop();
    344             
    345             switch(e.type) {
    346                 case 1:{
    347                     surgeryQ.push(e.idx); 
    348                     break;
    349                 }
    350                 case 2:{
    351                     recoveryQ.push(e.idx);
    352                     break;
    353                 }
    354                 case 3:{
    355                     roomQ.push(e.idx);
    356                     break;
    357                 }
    358                 case 4:{
    359                     bedQ.push(e.idx);
    360                     break;
    361                 }
    362                 default:{
    363                     assert(false);
    364                 }
    365             } 
    366         }
    367         
    368         // 如果有人等待做手术并且有手术室可用,就分配手术室 
    369         while(!surgeryQ.empty() && !roomQ.empty()) {
    370             int pid = surgeryQ.front(); surgeryQ.pop();
    371             int rid = roomQ.top(); roomQ.pop();
    372             Patient &p = roster[pid];
    373             Facility &f = rooms[rid];
    374             
    375             p.surgeryRoomId = f.id;
    376             p.surgeryBeginTime = nowTime;
    377             p.surgeryEndTime = p.surgeryBeginTime + p.surgeryTime;
    378             
    379             f.timeUsed += p.surgeryTime;
    380             
    381             Q.push(Event(2, pid, p.surgeryEndTime));
    382             Q.push(Event(3, rid, p.surgeryEndTime + surgeryResetTime));
    383         }
    384         
    385         // 如果有人等待恢复并且有恢复室可用,就分配恢复室 
    386         while(!recoveryQ.empty() && !bedQ.empty()) {
    387             int pid = recoveryQ.top(); recoveryQ.pop();
    388             int bid = bedQ.top(); bedQ.pop();
    389             Patient &p = roster[pid];
    390             Facility &f = beds[bid];
    391             
    392             p.recoveryRoomId = f.id;
    393             p.recoveryBeginTime = nowTime + tranTime;
    394             p.recoveryEndTime = p.recoveryBeginTime + p.recoveryTime;
    395             
    396             f.timeUsed += p.recoveryTime;
    397             
    398             endTime = max(endTime, p.recoveryEndTime);
    399             
    400             Q.push(Event(4, bid, p.recoveryEndTime + recoveryResetTime));
    401         }
    402     }
    403 }
    404 
    405 int main() {
    406     //freopen("MyOutput.txt","w",stdout);
    407     //freopen("input.txt","r",stdin);
    408     //INIT();
    409     while(readData()) {
    410         solve();
    411         totalTime = endTime.val - startTime.val;
    412         printSheet();
    413         cout << endl;
    414     }
    415     return 0;
    416 }
    View Code
  • 相关阅读:
    11,Django组件分页器
    10,Django于ajax
    阿里云安装Nexus搭建Maven私有仓库
    maven 自动部署到tomcat
    linux 7.2 下安装maven
    小程序防止遮罩层穿透
    Linux 下安装JDK
    Linux 命令未自动提示补全
    nginx 、tomcat 集群配置、shiro Session 共享
    nginx负载均衡配置
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/11389093.html
Copyright © 2020-2023  润新知