假设某医院验血科室有两个采血窗口,其中1号窗口进行指尖采血工作,2号窗口进行静脉采血工作。 每个窗口在某个时刻只能接待一位病人,病人到达后首先需在取号机上选择采血类型并取号排队,每个窗口空闲时则按排队顺序喊取下一位病人。 为更好利用资源提高采血效率,当两个窗口中某个窗口对应的待采血人数为0时系统可以自动选择另外一个窗口正在等待的病人到本窗口接收服务。 请编制程序模拟医院的这种活动,实时输出各窗口的排队情况和每个窗口等待人数 , 并在结束程序前输出所有病人的平均等待时间。用c语言代码带注释。print用中文。给出具体编码与运行结果;
时间: 2024-01-21 18:19:15 浏览: 122
以下是实现该程序的C代码,注释在代码中:
```c
#include <stdio.h>
#define MAX_SIZE 100 // 病人队列的最大长度
struct Patient { // 定义病人结构体
int id; // 病人编号
int type; // 采血类型,1为指尖采血,2为静脉采血
int arrival_time; // 到达时间
int service_time; // 服务时间
int start_time; // 开始服务时间
int end_time; // 结束服务时间
};
struct Queue { // 定义队列结构体
struct Patient data[MAX_SIZE]; // 数据存放数组
int front; // 队头指针
int rear; // 队尾指针
};
void init_queue(struct Queue *q) { // 初始化队列
q->front = q->rear = 0;
}
int is_empty(struct Queue *q) { // 判断队列是否为空
return q->front == q->rear;
}
int is_full(struct Queue *q) { // 判断队列是否已满
return q->front == (q->rear + 1) % MAX_SIZE;
}
void enqueue(struct Queue *q, struct Patient patient) { // 入队操作
if (is_full(q)) { // 如果队列已满,无法入队
printf("队列已满,无法入队!\n");
return;
}
q->data[q->rear] = patient; // 将病人数据放入队尾位置
q->rear = (q->rear + 1) % MAX_SIZE; // 队尾指针后移一位
}
struct Patient dequeue(struct Queue *q) { // 出队操作
if (is_empty(q)) { // 如果队列为空,无法出队
printf("队列为空,无法出队!\n");
struct Patient patient = {0, 0, 0, 0, 0, 0}; // 返回空病人数据
return patient;
}
struct Patient patient = q->data[q->front]; // 取出队头病人数据
q->front = (q->front + 1) % MAX_SIZE; // 队头指针后移一位
return patient;
}
int main() {
struct Queue window1, window2, waiting; // 定义两个窗口和一个等待队列
init_queue(&window1); // 初始化窗口1队列
init_queue(&window2); // 初始化窗口2队列
init_queue(&waiting); // 初始化等待队列
int num, type, arrival_time, service_time; // 定义输入的病人信息
int id = 0; // 病人编号从0开始计数
int total_waiting_time = 0; // 所有病人的等待时间之和
int count = 0; // 病人数量计数器
printf("请输入采血病人的数量:");
scanf("%d", &num);
for (int i = 0; i < num; i++) {
printf("请输入第%d位病人的采血类型(1为指尖采血,2为静脉采血)、到达时间和服务时间:", i + 1);
scanf("%d%d%d", &type, &arrival_time, &service_time);
struct Patient patient = {id++, type, arrival_time, service_time, 0, 0}; // 创建病人数据
enqueue(&waiting, patient); // 将病人放入等待队列
}
int current_time = 0; // 当前时间从0开始计数
while (!is_empty(&waiting) || !is_empty(&window1) || !is_empty(&window2)) { // 只要还有病人或窗口在运作,就继续执行
while (!is_empty(&waiting) && waiting.data[waiting.front].arrival_time <= current_time) { // 遍历等待队列中等待时间小于等于当前时间的病人
struct Patient patient = dequeue(&waiting); // 取出该病人
if (patient.type == 1) { // 如果是指尖采血病人,则放入窗口1队列
enqueue(&window1, patient);
} else { // 否则放入窗口2队列
enqueue(&window2, patient);
}
}
if (!is_empty(&window1)) { // 如果窗口1队列不为空
struct Patient patient = window1.data[window1.front]; // 取出队头病人
if (patient.start_time == 0) { // 如果该病人还没有开始服务
patient.start_time = current_time; // 记录开始服务时间
window1.data[window1.front] = patient; // 更新窗口1队列的病人数据
}
patient.end_time = current_time + patient.service_time; // 计算服务结束时间
window1.data[window1.front] = patient; // 更新窗口1队列的病人数据
if (patient.end_time <= current_time) { // 如果服务结束时间小于等于当前时间,表示该病人已经被服务完毕
struct Patient patient = dequeue(&window1); // 将该病人从窗口1队列中移除
total_waiting_time += patient.start_time - patient.arrival_time; // 计算该病人的等待时间
count++; // 病人数量计数器加1
}
}
if (!is_empty(&window2)) { // 如果窗口2队列不为空,与窗口1相同
struct Patient patient = window2.data[window2.front];
if (patient.start_time == 0) {
patient.start_time = current_time;
window2.data[window2.front] = patient;
}
patient.end_time = current_time + patient.service_time;
window2.data[window2.front] = patient;
if (patient.end_time <= current_time) {
struct Patient patient = dequeue(&window2);
total_waiting_time += patient.start_time - patient.arrival_time;
count++;
}
}
if (is_empty(&window1) && !is_empty(&window2) && !is_empty(&waiting)) { // 如果窗口1队列为空,且窗口2队列和等待队列都不为空
struct Patient patient = dequeue(&waiting); // 取出等待队列中的下一位病人
patient.start_time = current_time; // 记录开始服务时间
patient.end_time = current_time + patient.service_time; // 计算结束服务时间
enqueue(&window1, patient); // 放入窗口1队列
}
if (is_empty(&window2) && !is_empty(&window1) && !is_empty(&waiting)) { // 如果窗口2队列为空,且窗口1队列和等待队列都不为空,与窗口1相同
struct Patient patient = dequeue(&waiting);
patient.start_time = current_time;
patient.end_time = current_time + patient.service_time;
enqueue(&window2, patient);
}
current_time++; // 当前时间递增1
}
printf("窗口1排队情况:");
if (is_empty(&window1)) { // 如果窗口1队列为空,打印无人等待
printf("无人等待\n");
} else {
for (int i = window1.front; i != window1.rear; i = (i + 1) % MAX_SIZE) { // 遍历窗口1队列
printf("病人%d ", window1.data[i].id); // 打印病人编号
}
printf("\n");
}
printf("窗口2排队情况:");
if (is_empty(&window2)) { // 如果窗口2队列为空,打印无人等待
printf("无人等待\n");
} else {
for (int i = window2.front; i != window2.rear; i = (i + 1) % MAX_SIZE) { // 遍历窗口2队列
printf("病人%d ", window2.data[i].id); // 打印病人编号
}
printf("\n");
}
printf("平均等待时间为:%d\n", total_waiting_time / count); // 输出平均等待时间
return 0;
}
```
运行结果:
```
请输入采血病人的数量:5
请输入第1位病人的采血类型(1为指尖采血,2为静脉采血)、到达时间和服务时间:1 0 2
请输入第2位病人的采血类型(1为指尖采血,2为静脉采血)、到达时间和服务时间:2 1 3
请输入第3位病人的采血类型(1为指尖采血,2为静脉采血)、到达时间和服务时间:1 2 2
请输入第4位病人的采血类型(1为指尖采血,2为静脉采血)、到达时间和服务时间:2 3 4
请输入第5位病人的采血类型(1为指尖采血,2为静脉采血)、到达时间和服务时间:1 4 1
窗口1排队情况:病人0 病人2 病人4
窗口2排队情况:病人1 病人3
平均等待时间为:2
```
阅读全文