/*
借鉴了:
http://blog.csdn.net/xienaoban/article/details/52895020
收获 & 总结:
1. cout的输出格式控制
http://blog.csdn.net/xienaoban/article/details/52895020
2.vector可在定义时,指定大小并同一初始化
http://blog.chinaunix.net/uid-26000296-id-3785610.html
*/
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <iomanip>
#include <algorithm>
#define rep(i, n) for (int i = 1; i <= (n); i++)
#define output_time(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& r) const
{
if (at != r.at) return at > r.at;
return id > r.id;
} //at为手术结束时间,id为手术室编号,优先队列优先级更大的先出队,故以这样的方式重载
};
struct patient
{
string name;
int id, room, bed, top, tre, t1, t2, t3, t4;
};
bool mycmp(const patient &a, const patient &b)
{
if (a.t2 != b.t2) return a.t2 < b.t2;
return a.room < b.room;
}//at为手术结束时间,id为手术室编号,优先队列优先级更大的先出队,故以这样的方式重载
int n, m, T, t1, t2, t3, k, Time;
int main()
{
cin.tie(0);
cin.sync_with_stdio(false);
while (cin >> n)
{
cin >> m >> T >> t1 >> t2 >> t3 >> k;
Time = 0, T *= 60;
vector<int> Top(n + 1, 0), Tre(m + 1, 0); // 手术室、恢复室的利用时间
vector<patient> patients(k + 1);
vector<int> Bre(m + 1, T); //保存恢复室恢复的时间
priority_queue<room> Rop; // room for operation
rep(i, n) Rop.push(room(i, T));
rep(i, k)
{
auto &now(patients[i]);
now.id = i;
room tp(Rop.top()); //按优先级出队,此时出队的是该病人该进入的手术室
Rop.pop();
cin >> now.name >> now.top >> now.tre; //在手术室、恢复室所待的时间
now.t1 = tp.at;
now.t2 = now.t1 + now.top; //手术结束时间
now.t3 = now.t2 + t1; //t1:从手术室到恢复室
now.t4 = now.t3 + now.tre;
now.room = tp.id; //病人所在的手术室序号
tp.at = now.t2 + t2; //手术室再次可用的时间,为病人离开时间,加上手术室恢复时间
Top[tp.id] += now.top; //该手术室使用时间(最后要算时间利用率!)
Rop.push(tp);
}
sort(patients.begin() + 1, patients.end(), mycmp);
rep(i, k)
{
auto &now(patients[i]);
int j;
for (j = 1; j <= m; j++)
if (Bre[j] <= now.t2) break;
now.bed = j;
Bre[j] = now.t4 + t3;
Tre[j] += now.tre; //该恢复室使用时间(最后要算时间利用率!)
Time = max(Time, now.t4);
}
sort(patients.begin() + 1, patients.end(), [] (patient &a, patient &b) {return a.id < b.id;});
cout << " Patient Operating Room Recovery Room\n"
<< " # Name Room# Begin End Bed# Begin End\n"
<< " ------------------------------------------------------\n";
rep(i, k)
{
auto &now (patients[i]);
cout << setw(2) << i << " " << left << setw(10) << now.name << right << setw(2) << now.room << " "
<< output_time(now.t1) << " " << output_time(now.t2) << " " << setw(2) << now.bed << " "
<< output_time(now.t3) << " " << output_time(now.t4) << endl;
}
cout << endl
<< "Facility Utilization" << endl << "Type # Minutes % Used" << endl
<< "-------------------------" << endl;
rep(i, n)
{
cout << "Room " << setw(2) << i << setw(8) << Top[i] << setw(8) << fixed << setprecision(2)
<< (Top[i] * 100.0 / (float)(Time - T) ) << endl;
}
rep(i, m)
{
cout << "Bed " << setw(2) << i << setw(8) << Tre[i] << setw(8)
<< fixed << setprecision(2) << (Tre[i] * 100.0 / (float)(Time - T) ) << endl;
}
cout << endl;
}
return 0;
}
/*
看过的法二:
收获 && 总结:
1. http://blog.csdn.net/wusecaiyun/article/details/48879899
queue没有clear方法,但因为该题多组数据,要么在非空时,不断调用pop();要么在while循环内定义queue,则定义后默认为空,每次进入循环重新定义(法一采用)
2. 这个博主对结构体的设计,感觉比法一更有条理,含义也更加清楚
ROOM_BED 保存床位的使用时间(手术室床位 / 恢复室床位)和利用率(使用时间除以整个过程的总时间)
PATIENT 保存病人信息,包括姓名、病人本身序号、手术室和恢复室的序号
在手术室、恢复室的起止时间(除了第一组以外,停止时间是加上了手术 / 恢复室的准备时间的),手术、恢复的持续时间
ROOM 保存手术/恢复室被使用的起止时间
其实法一基本也存的是这些数据,但是没有法二中的直观,可见变量取名是挺重要的一件事
*/