医院里有n(n≤10)个手术室和m(m≤30)个恢复室。每个病人首先会被分配到一个手术室,手术后会被分配到一个恢复室。从任意手术室到任意恢复室的时间均为t1,准备一个手术室和恢复室的时间分别为t2和t3(一开始所有手术室和恢复室均准备好,只有接待完一个病人之后才需要为下一个病人准备)。
k名(k≤100)病人按照花名册顺序排队,T点钟准时开放手术室。每当有准备好的手术室时,队首病人进入其中编号最小的手术室。手术结束后,病人应立刻进入编号最小的恢复室。如果有多个病人同时结束手术,在编号较小的手术室做手术的病人优先进入编号较小的恢复室。输入保证病人无须排队等待恢复室。
输入n、m、T、t1、t2、t3、k和k名病人的名字、手术时间和恢复时间,模拟这个过程。
样例:
输入
5 12 07 5 15 10 16
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
86 181
White
92 140
输出
Patient Operating Room Recovery Room
# Name Room# Begin End Bed# Begin End
------------------------------------------------------
1 Jones 1 7:00 7:28 3 7:33 9:53
2 Smith 2 7:00 9:00 1 9:05 12:25
3 Thompson 3 7:00 7:23 2 7:28 8:43
4 Albright 4 7:00 7:19 1 7:24 8:46
5 Poucher 5 7:00 9:13 5 9:18 12:47
6 Comer 4 7:34 8:48 4 8:53 10:34
7 Perry 3 7:38 9:11 2 9:16 12:24
8 Page 1 7:43 9:34 6 9:39 13:22
9 Roggio 4 9:03 10:12 9 10:17 12:19
10 Brigham 2 9:15 9:57 8 10:02 11:21
11 Nute 3 9:26 9:48 7 9:53 11:04
12 Young 5 9:28 10:06 3 10:11 12:31
13 Bush 1 9:49 10:15 10 10:20 12:21
14 Cates 3 10:03 12:03 8 12:08 16:16
15 Johnson 2 10:12 11:38 4 11:43 14:44
16 White 5 10:21 11:53 7 11:58 14:18
Facility Utilization
Type # Minutes % Used
-------------------------
Room 1 165 29.68
Room 2 248 44.60
Room 3 258 46.40
Room 4 162 29.14
Room 5 263 47.30
Bed 1 282 50.72
Bed 2 263 47.30
Bed 3 280 50.36
Bed 4 282 50.72
Bed 5 209 37.59
Bed 6 223 40.11
Bed 7 211 37.95
Bed 8 327 58.81
Bed 9 122 21.94
Bed 10 121 21.76
Bed 11 0 0.00
Bed 12 0 0.00
解法:
use std::{cmp::Ordering, collections::BinaryHeap, io};
#[derive(Debug)]
struct Patient {
id: usize,
name: String,
operation_time: usize,
recovery_time: usize,
room_id: usize,
room_begin_time: usize,
room_end_time: usize,
bed_id: usize,
bed_begin_time: usize,
bed_end_time: usize,
}
#[derive(Debug, PartialEq, Eq)]
struct Room {
id: usize,
start_available_time: usize,
}
impl Ord for Room {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
if self.start_available_time != other.start_available_time {
if self.start_available_time < other.start_available_time {
Ordering::Greater
} else {
Ordering::Less
}
} else if self.id < other.id {
Ordering::Greater
} else {
Ordering::Less
}
}
}
impl PartialOrd for Room {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
fn main() {
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
let v: Vec<usize> = buf.split_whitespace().map(|e| e.parse().unwrap()).collect();
let n = v[0];
let m = v[1];
let start_time = v[2] * 60;
let t1 = v[3];
let t2 = v[4];
let t3 = v[5];
let k = v[6];
let mut rooms = BinaryHeap::new();
for i in 0..n {
let room = Room {
id: i + 1,
start_available_time: start_time,
};
rooms.push(room);
}
let mut patients: Vec<Patient> = vec![];
for i in 0..k {
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
let name = buf.trim().to_string();
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
let t: Vec<usize> = buf.split_whitespace().map(|e| e.parse().unwrap()).collect();
let patient = Patient {
id: i + 1,
name: name,
operation_time: t[0],
recovery_time: t[1],
room_id: 0,
room_begin_time: 0,
room_end_time: 0,
bed_id: 0,
bed_begin_time: 0,
bed_end_time: 0,
};
patients.push(patient);
}
let mut room_used_time: Vec<usize> = vec![0; n];
for patient in patients.iter_mut() {
let aroom = rooms.pop().unwrap();
patient.room_id = aroom.id;
patient.room_begin_time = aroom.start_available_time;
patient.room_end_time = patient.room_begin_time + patient.operation_time;
rooms.push(Room {
id: aroom.id,
start_available_time: patient.room_end_time + t2,
});
room_used_time[aroom.id - 1] += patient.operation_time;
}
patients.sort_by(|a, b| {
if a.room_end_time != b.room_end_time {
if a.room_end_time < b.room_end_time {
Ordering::Less
} else {
Ordering::Greater
}
} else {
if a.room_id < b.room_id {
Ordering::Less
} else {
Ordering::Greater
}
}
});
let mut beds: Vec<usize> = vec![start_time; m];
let mut bed_used_time: Vec<usize> = vec![0; m];
let mut final_time = start_time;
for patient in patients.iter_mut() {
for j in 0..m {
if beds[j] <= patient.room_end_time {
patient.bed_id = j + 1;
patient.bed_begin_time = patient.room_end_time + t1;
patient.bed_end_time = patient.bed_begin_time + patient.recovery_time;
beds[j] = patient.bed_end_time + t3;
bed_used_time[j] += patient.recovery_time;
final_time = final_time.max(patient.bed_end_time);
break;
}
}
}
patients.sort_by(|a, b| a.id.cmp(&b.id));
println!(" Patient Operating Room Recovery Room");
println!(" # Name Room# Begin End Bed# Begin End");
println!(" ------------------------------------------------------");
for i in patients.iter() {
print!("{:2} {:<10}", i.id, i.name);
print!(
"{:2} {:2}:{:02} {:2}:{:02}",
i.room_id,
i.room_begin_time / 60,
i.room_begin_time % 60,
i.room_end_time / 60,
i.room_end_time % 60
);
println!(
" {:2} {:2}:{:02} {:2}:{:02}",
i.bed_id,
i.bed_begin_time / 60,
i.bed_begin_time % 60,
i.bed_end_time / 60,
i.bed_end_time % 60
);
}
println!();
println!("Facility Utilization");
println!("Type # Minutes % Used");
println!("-------------------------");
let all_time = final_time - start_time;
for i in 0..n {
println!(
"Room {:2} {:4} {:5.2}",
i + 1,
room_used_time[i],
100.0 * room_used_time[i] as f64 / all_time as f64
);
}
for i in 0..m {
println!(
"Bed {:2} {:4} {:5.2}",
i + 1,
bed_used_time[i],
100.0 * bed_used_time[i] as f64 / all_time as f64
);
}
}