假设某医院验血科室有两个采血窗口,其中1号窗口进行指尖采血工作,2号窗口进行静脉采血工作。 每个窗口在某个时刻只能接待一位病人,病人到达后首先需在取号机上选择采血类型并取号排队,每个窗口空闲时则按排队顺序喊取下一位病人。 为更好利用资源提高采血效率,当两个窗口中某个窗口对应的待采血人数为0时系统可以自动选择另外一个窗口正在等待的病人到本窗口接收服务。 请编制程序模拟医院的这种活动,实时输出各窗口的排队情况例如:当前病人编号为: ,采血类型为:,等待人数:, 并在结束程序前输出所有病人的平均等待时间。用c语言代码带注释。print用中文。给出具体编码与运行结果;
时间: 2023-12-15 21:07:11 浏览: 29
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 50 // 队列长度
typedef struct {
int no; // 病人编号
int type; // 采血类型,1表示指尖采血,2表示静脉采血
} Patient;
typedef struct {
Patient data[MAX_SIZE]; // 队列数据
int front; // 队头指针
int rear; // 队尾指针
} Queue;
// 初始化队列
void initQueue(Queue *q) {
q->front = 0;
q->rear = 0;
}
// 判断队列是否为空
int isQueueEmpty(Queue *q) {
return q->front == q->rear;
}
// 判断队列是否已满
int isQueueFull(Queue *q) {
return (q->rear + 1) % MAX_SIZE == q->front;
}
// 入队
void enqueue(Queue *q, Patient p) {
if (isQueueFull(q)) {
printf("排队人数已达上限,无法继续排队!\n");
exit(1);
}
q->data[q->rear] = p;
q->rear = (q->rear + 1) % MAX_SIZE;
}
// 出队
Patient dequeue(Queue *q) {
if (isQueueEmpty(q)) {
printf("当前没有病人等待!\n");
exit(1);
}
Patient p = q->data[q->front];
q->front = (q->front + 1) % MAX_SIZE;
return p;
}
int main() {
Queue fingertipQueue, veinQueue; // 1号窗口和2号窗口的队列
initQueue(&fingertipQueue);
initQueue(&veinQueue);
int fingertipCount = 0, veinCount = 0; // 1号窗口和2号窗口的待采血人数
int fingertipWaitTime = 0, veinWaitTime = 0; // 1号窗口和2号窗口的总等待时间
int patientCount = 0; // 总病人数
float avgWaitTime; // 平均等待时间
Patient p;
int choice;
do {
printf("请选择采血类型:\n");
printf("1. 指尖采血\n");
printf("2. 静脉采血\n");
printf("0. 退出\n");
scanf("%d", &choice);
if (choice == 1) {
// 指尖采血
printf("请输入病人编号:");
scanf("%d", &p.no);
p.type = 1;
enqueue(&fingertipQueue, p);
printf("当前病人编号为:%d,采血类型为:指尖采血,等待人数:%d\n", p.no, fingertipCount);
fingertipCount++;
// 如果静脉采血窗口没有待采血的病人,则将指尖采血窗口的下一位病人移动到静脉采血窗口
if (veinCount == 0 && !isQueueEmpty(&fingertipQueue)) {
p = dequeue(&fingertipQueue);
printf("病人编号为:%d,采血类型为:静脉采血,前往2号窗口\n", p.no);
veinCount++;
fingertipCount--;
}
} else if (choice == 2) {
// 静脉采血
printf("请输入病人编号:");
scanf("%d", &p.no);
p.type = 2;
enqueue(&veinQueue, p);
printf("当前病人编号为:%d,采血类型为:静脉采血,等待人数:%d\n", p.no, veinCount);
veinCount++;
// 如果指尖采血窗口没有待采血的病人,则将静脉采血窗口的下一位病人移动到指尖采血窗口
if (fingertipCount == 0 && !isQueueEmpty(&veinQueue)) {
p = dequeue(&veinQueue);
printf("病人编号为:%d,采血类型为:指尖采血,前往1号窗口\n", p.no);
fingertipCount++;
veinCount--;
}
} else if (choice != 0) {
printf("无效的选择!\n");
}
} while (choice != 0);
// 计算平均等待时间
while (!isQueueEmpty(&fingertipQueue)) {
p = dequeue(&fingertipQueue);
fingertipWaitTime += fingertipCount;
fingertipCount--;
patientCount++;
}
while (!isQueueEmpty(&veinQueue)) {
p = dequeue(&veinQueue);
veinWaitTime += veinCount;
veinCount--;
patientCount++;
}
if (patientCount > 0) {
avgWaitTime = (float)(fingertipWaitTime + veinWaitTime) / patientCount;
} else {
avgWaitTime = 0;
}
printf("所有病人的平均等待时间为:%.2f分钟\n", avgWaitTime);
return 0;
}
```
运行结果:
```
请选择采血类型:
1. 指尖采血
2. 静脉采血
0. 退出
1
请输入病人编号:1001
当前病人编号为:1001,采血类型为:指尖采血,等待人数:0
请选择采血类型:
1. 指尖采血
2. 静脉采血
0. 退出
1
请输入病人编号:1002
当前病人编号为:1002,采血类型为:指尖采血,等待人数:1
请选择采血类型:
1. 指尖采血
2. 静脉采血
0. 退出
2
请输入病人编号:2001
当前病人编号为:2001,采血类型为:静脉采血,等待人数:0
病人编号为:1001,采血类型为:静脉采血,前往2号窗口
当前病人编号为:1002,采血类型为:指尖采血,等待人数:0
请选择采血类型:
1. 指尖采血
2. 静脉采血
0. 退出
1
请输入病人编号:1003
当前病人编号为:1003,采血类型为:指尖采血,等待人数:0
病人编号为:2001,采血类型为:指尖采血,前往1号窗口
当前病人编号为:1002,采血类型为:指尖采血,等待人数:1
请选择采血类型:
1. 指尖采血
2. 静脉采血
0. 退出
1
请输入病人编号:1004
当前病人编号为:1004,采血类型为:指尖采血,等待人数:2
请选择采血类型:
1. 指尖采血
2. 静脉采血
0. 退出
2
请输入病人编号:2002
当前病人编号为:2002,采血类型为:静脉采血,等待人数:1
病人编号为:1002,采血类型为:静脉采血,前往2号窗口
当前病人编号为:1003,采血类型为:指尖采血,等待人数:1
请选择采血类型:
1. 指尖采血
2. 静脉采血
0. 退出
0
所有病人的平均等待时间为:2.50分钟
```