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
原文地址:https://www.cnblogs.com/zaq19970105/p/11389093.html