题目链接: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. 手术完成后应当立即选择恢复室并移动。

代码如下

 #include <bits/stdc++.h>
using namespace std; #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define Rep(i,n) for (int i = 0; i < (int)(n); ++i)
#define For(i,s,t) for (int i = (int)(s); i <= (int)(t); ++i)
#define rFor(i,t,s) for (int i = (int)(t); i >= (int)(s); --i)
#define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
#define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define LOWBIT(x) ((x)&(-x)) #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define UNIQUE(x) x.erase(unique(x.begin(), x.end()), x.end())
#define REMOVE(x, c) x.erase(remove(x.begin(), x.end(), c), x.end()); // 删去 x 中所有 c
#define TOLOWER(x) transform(x.begin(), x.end(), x.begin(),::tolower);
#define TOUPPER(x) transform(x.begin(), x.end(), x.begin(),::toupper); #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,0x3f,sizeof(a))
#define msM(a) memset(a,-1,sizeof(a)) #define MP make_pair
#define PB push_back
#define ft first
#define sd second template<typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
in >> p.first >> p.second;
return in;
} template<typename T>
istream &operator>>(istream &in, vector<T> &v) {
for (auto &x: v)
in >> x;
return in;
} template<typename T>
ostream &operator<<(ostream &out, vector<T> &v) {
Rep(i, v.size()) out << v[i] << " \n"[i == v.size() - ];
return out;
} template<typename T1, typename T2>
ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
out << "[" << p.first << ", " << p.second << "]" << "\n";
return out;
} inline int gc(){
static const int BUF = 1e7;
static char buf[BUF], *bg = buf + BUF, *ed = bg; if(bg == ed) fread(bg = buf, , BUF, stdin);
return *bg++;
} inline int ri(){
int x = , f = , c = gc();
for(; c<||c>; f = c=='-'?-:f, c=gc());
for(; c>&&c<; x = x* + c - , c=gc());
return x*f;
} template<class T>
inline string toString(T x) {
ostringstream sout;
sout << x;
return sout.str();
} inline int toInt(string s) {
int v;
istringstream sin(s);
sin >> v;
return v;
} //min <= aim <= max
template<typename T>
inline bool BETWEEN(const T aim, const T min, const T max) {
return min <= aim && aim <= max;
} typedef unsigned int uI;
typedef long long LL;
typedef unsigned long long uLL;
typedef vector< int > VI;
typedef vector< bool > VB;
typedef vector< char > VC;
typedef vector< double > VD;
typedef vector< string > VS;
typedef vector< LL > VL;
typedef vector< VI > VVI;
typedef vector< VB > VVB;
typedef vector< VS > VVS;
typedef vector< VL > VVL;
typedef vector< VVI > VVVI;
typedef vector< VVL > VVVL;
typedef pair< int, int > PII;
typedef pair< LL, LL > PLL;
typedef pair< int, string > PIS;
typedef pair< string, int > PSI;
typedef pair< string, string > PSS;
typedef pair< double, double > PDD;
typedef vector< PII > VPII;
typedef vector< PLL > VPLL;
typedef vector< VPII > VVPII;
typedef vector< VPLL > VVPLL;
typedef vector< VS > VVS;
typedef map< int, int > MII;
typedef unordered_map< int, int > uMII;
typedef map< LL, LL > MLL;
typedef map< string, int > MSI;
typedef map< int, string > MIS;
typedef multiset< int > mSI;
typedef set< int > SI;
typedef stack< int > SKI;
typedef deque< int > DQI;
typedef queue< int > QI;
typedef priority_queue< int > PQIMax;
typedef priority_queue< int, VI, greater< int > > PQIMin;
const double EPS = 1e-;
const LL inf = 0x7fffffff;
const LL infLL = 0x7fffffffffffffffLL;
const LL mod = 1e9 + ;
const int maxN = 1e4 + ;
const LL ONE = ;
const LL evenBits = 0xaaaaaaaaaaaaaaaa;
const LL oddBits = 0x5555555555555555; struct Time {
int val = ; // 总的分钟数 bool operator< (const Time &x) const {
return val < x.val;
} bool operator== (const Time &x) const {
return val == x.val;
} bool operator> (const Time &x) const {
return val > x.val;
} Time operator+ (const int &k) const {
Time ret;
ret.val = val + k;
return ret;
} Time operator+ (const Time &x) const {
Time ret;
ret.val = val + x.val;
return ret;
} string getString() {
string ret;
ret = toString(val / ) + ":";
if((val % ) / == ) ret += "";
ret += toString(val % );
return ret;
}
}; struct Patient {
int id; // 病人在,名册上的 id
string name; // 病人名字
int surgeryTime; // 病人手术时间
int recoveryTime; // 病人恢复时间 int surgeryRoomId; // 所进行手术的手术室 id
Time surgeryBeginTime; // 手术开始时间
Time surgeryEndTime; // 手术结束时间 int recoveryRoomId; // 所进行恢复的恢复室 id
Time recoveryBeginTime; // 恢复开始时间
Time recoveryEndTime; // 恢复结束时间 Patient(int x) : id(x) {}
}; istream& operator >> (istream& in, Patient& x){
in >> x.name >> x.surgeryTime >> x.recoveryTime;
return in;
} ostream& operator << (ostream& out, Patient& x){
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());
return out;
} struct Facility {
int id; // 设施 id
string type; // 设施类型
int timeUsed; // 设施被使用的时间
double usedPercent; // 使用时间百分比 Facility(int x, string y) {
id = x;
type = y;
timeUsed = ;
usedPercent = ;
}
}; ostream& operator << (ostream& out, const Facility& x) {
printf("%-4s %2d %7d %6.2f", x.type.c_str(), x.id, x.timeUsed, x.usedPercent);
return out;
} struct Event {
// 1 代表患者可进行手术事件
// 2 代表患者可进行恢复事件
// 3 代表手术室空闲事件
// 4 代表恢复室空闲事件
int type;
int idx; // 对应数组下表
Time time; // 事件可进行时间 Event(int x, int y, Time z) {
type = x;
idx = y;
time = z;
} bool operator< (const Event &x) const {
return time > x.time || time == x.time && idx > x.idx;
}
}; int N; // 手术室数量,小于等于 10
vector< Facility > rooms; // 手术室房间数组
int M; // 恢复室数量,小于等于 30
vector< Facility > beds; // 恢复室床数组
Time startTime; // 一天中医院的开始营业时间,整点,24小时格式
Time endTime; // 所有手术的结束时间
int totalTime; // 手术总持续时间
int tranTime; // 手术室转移恢复室时间(分钟)
int surgeryResetTime; // 手术室准备时间(分钟)
int recoveryResetTime; // 恢复室准备时间(分钟)
vector< Patient > roster; // 病人名册
int patientNum; // 病人人数
int tmp; struct RoomCmp {
bool operator() (int x, int y) {
return rooms[x].id > rooms[y].id;
}
}; struct BedCmp {
bool operator() (int x, int y) {
return beds[x].id > beds[y].id;
}
}; struct RecoveryComp {
bool operator() (int x, int y) {
if(roster[x].surgeryEndTime == roster[y].surgeryEndTime) return roster[x].surgeryRoomId > roster[y].surgeryRoomId;
return roster[x].surgeryEndTime > roster[y].surgeryEndTime;
}
}; priority_queue< Event > Q; // 活动队列
QI surgeryQ; // 等待手术队列
priority_queue< int, VI, RecoveryComp > recoveryQ; // 等待恢复队列
priority_queue< int, VI, RoomCmp > roomQ; // 手术室空闲队列
priority_queue< int, VI, BedCmp > bedQ; // 恢复室空闲队列 void init() {
rooms.clear();
beds.clear();
endTime = startTime;
roster.clear(); while(!Q.empty()) Q.pop();
while(!surgeryQ.empty()) surgeryQ.pop();
while(!recoveryQ.empty()) recoveryQ.pop();
while(!roomQ.empty()) roomQ.pop();
while(!bedQ.empty()) bedQ.pop();
} bool readData() {
if(!(cin >> N >> M >> tmp >> tranTime >> surgeryResetTime >> recoveryResetTime >> patientNum)) return false;
startTime.val = tmp * ; init(); Rep(i, N) rooms.PB(Facility(i + , "Room"));
Rep(i, M) beds.PB(Facility(i + , "Bed")); Rep(i, patientNum) {
roster.PB(Patient(i + ));
cin >> roster[i];
} return true;
} void printSheet() {
printf(" Patient Operating Room Recovery Room\n");
printf(" # Name Room# Begin End Bed# Begin End\n");
printf(" ------------------------------------------------------\n");
Rep(i, patientNum) cout << roster[i] << endl; cout << endl; printf("Facility Utilization\n");
printf("Type # Minutes % Used\n");
printf("-------------------------\n");
Rep(i, N) {
if(totalTime) rooms[i].usedPercent = 100.0 * rooms[i].timeUsed / totalTime;
cout << rooms[i] << endl;
}
Rep(i, M) {
if(totalTime) beds[i].usedPercent = 100.0 * beds[i].timeUsed / totalTime;
cout << beds[i] << endl;
}
} void solve() {
Time nowTime;
Rep(i, patientNum) Q.push(Event(, i, startTime));
Rep(i, N) Q.push(Event(, i, startTime));
Rep(i, M) Q.push(Event(, i, startTime)); while(!Q.empty()) {
nowTime = Q.top().time; while(!Q.empty() && nowTime == Q.top().time) { // 把这个时间到到达的活动全取出来
Event e = Q.top(); Q.pop(); switch(e.type) {
case :{
surgeryQ.push(e.idx);
break;
}
case :{
recoveryQ.push(e.idx);
break;
}
case :{
roomQ.push(e.idx);
break;
}
case :{
bedQ.push(e.idx);
break;
}
default:{
assert(false);
}
}
} // 如果有人等待做手术并且有手术室可用,就分配手术室
while(!surgeryQ.empty() && !roomQ.empty()) {
int pid = surgeryQ.front(); surgeryQ.pop();
int rid = roomQ.top(); roomQ.pop();
Patient &p = roster[pid];
Facility &f = rooms[rid]; p.surgeryRoomId = f.id;
p.surgeryBeginTime = nowTime;
p.surgeryEndTime = p.surgeryBeginTime + p.surgeryTime; f.timeUsed += p.surgeryTime; Q.push(Event(, pid, p.surgeryEndTime));
Q.push(Event(, rid, p.surgeryEndTime + surgeryResetTime));
} // 如果有人等待恢复并且有恢复室可用,就分配恢复室
while(!recoveryQ.empty() && !bedQ.empty()) {
int pid = recoveryQ.top(); recoveryQ.pop();
int bid = bedQ.top(); bedQ.pop();
Patient &p = roster[pid];
Facility &f = beds[bid]; p.recoveryRoomId = f.id;
p.recoveryBeginTime = nowTime + tranTime;
p.recoveryEndTime = p.recoveryBeginTime + p.recoveryTime; f.timeUsed += p.recoveryTime; endTime = max(endTime, p.recoveryEndTime); Q.push(Event(, bid, p.recoveryEndTime + recoveryResetTime));
}
}
} int main() {
//freopen("MyOutput.txt","w",stdout);
//freopen("input.txt","r",stdin);
//INIT();
while(readData()) {
solve();
totalTime = endTime.val - startTime.val;
printSheet();
cout << endl;
}
return ;
}

UVA 212 Use of Hospital Facilities的更多相关文章

  1. [刷题]算法竞赛入门经典(第2版) 5-16/UVa212 - Use of Hospital Facilities

    题意:模拟患者做手术. 其条件为:医院有Nop个手术室.准备手术室要Mop分钟,另有Nre个恢复用的床.准备每张床要Mre分钟,早上Ts点整医院开张,从手术室手术完毕转移到回复床要Mtr分钟.现在医院 ...

  2. bash5.0参考手册

    Bash Reference Manual a.summary-letter { text-decoration: none } blockquote.indentedblock { margin-r ...

  3. UVA 10537 The Toll! Revisited uva1027 Toll(最短路+数学坑)

    前者之所以叫加强版,就是把uva1027改编了,附加上打印路径罢了. 03年的final题哦!!虽然是水题,但不是我这个只会做图论题的跛子能轻易尝试的——因为有个数学坑. 题意:运送x个货物从a-&g ...

  4. UVa 10012 - How Big Is It? 堆球问题 全排列+坐标模拟 数据

    题意:给出几个圆的半径,贴着底下排放在一个长方形里面,求出如何摆放能使长方形底下长度最短. 由于球的个数不会超过8, 所以用全排列一个一个计算底下的长度,然后记录最短就行了. 全排列用next_per ...

  5. UVA 10194 (13.08.05)

    :W Problem A: Football (aka Soccer)  The Problem Football the most popular sport in the world (ameri ...

  6. 紫书 习题 11-10 UVa 12264 (二分答案+最大流)

    书上写的是UVa 12011, 实际上是 12264 参考了https://blog.csdn.net/xl2015190026/article/details/51902823 这道题就是求出一种最 ...

  7. Fast Matrix Operations(UVA)11992

    UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y ...

  8. 1Z0-053 争议题目解析212

    1Z0-053 争议题目解析212 考试科目:1Z0-053 题库版本:V13.02 题库中原题为: 212.Note the following parameters settings in you ...

  9. uva 1354 Mobile Computing ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5

随机推荐

  1. 详解Linux运维工具:运维流程管理、运维发布变更、运维监控告警

     概述 应用上线后,运维工作才刚开始,具体工作可能包括:升级版本上线工作.服务监控.应用状态统计.日常服务状态巡检.突发故障处理.服务日常变更调整.集群管理.服务性能评估优化.数据库管理优化.随着应用 ...

  2. mybatis分页插件使用

    一:导入依赖 <!--分页插件--> <dependency> <groupId>com.github.pagehelper</groupId> < ...

  3. tfsenflow队列|tf.train.slice_input_producer|tf.train.Coordinator|tf.train.start_queue_runners

      #### ''' tf.train.slice_input_producer :定义样本放入文件名队列的方式[迭代次数,是否乱序],但此时文件名队列还没有真正写入数据 slice_input_pr ...

  4. java 重新学习 (七)

    一.mysql的InnoDB通过建立行级索确保事务完整性.,并以Oracle风格的共享锁来处理select语句.系统默认存储为InnoDB. 二. -- mysql 创建表 CREATE TABLE ...

  5. Comet OJ - Contest #12

    B 整个表格其实是一些联通块,取反操作不能跨连通块.所以直接统计一下每个连通块内数字不对的个数是不是偶数即可 #include<iostream> #include<cstring& ...

  6. Java原理领悟-线程池(Executor)

    线程池全面解析 什么是线程池? 很简单,简单看名字就知道是装有线程的池子,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程的复用. 线程池的好处 我 ...

  7. int类型转换舍入问题

    一,看代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sy ...

  8. 本地存储(sessionStrorage,localStorage)

    1.本地存储特性 1. 数据存储在用户浏览器中 2. 设置,读取方便,设置页面刷新不丢失数据 3. 容量较大,sessionStorage约5M,localStorage约20M 4. 只能存储字符串 ...

  9. 【知识强化】第六章 查找 6.3 B树和B+树

    本节课我们来学习本章的第一个难点,就是B树.那么B树它其实是一种数据结构,我们设计出这种数据结构就是为了提高我们的查找效率的,提高我们在磁盘上的查找效率.那么什么是B树呢?了解B树之前,我们先来回忆一 ...

  10. Angular的一些常用命令

    Angular的一些常用命令 cmd中创建项目: ng new taskmgr -si --style=scss //先不安装依赖,si 为skip install material需要scss样式的 ...