用循环队列模拟食堂排队
本文链接: https://blog.youkuaiyun.com/qq_42889402/article/details/109660292.
一、题目介绍和分析
1.题目内容
2.思路解析
1.使用循环队列先实现对排队过程的模拟。
模拟包括两部分:入队和出队。
模拟的稳定变量是时间,因此以时间打点,在每个时间节点处执行需要的操作即可。
本文最小时间间隔为:1min
2.根据具体问题具体求解。
ps:本文使用语言:c语言。但是不管用什么,解题思路都是一样的,不一样的只是实现方法。
3.问题分析
这道题有三个问题,依次分析如下:
1. 食堂平均每小时接待多少学生?
记录一小时内共出队了多少人即可。
ps:更严谨的模拟应该是:连续模拟较长时间,然后从中间某个时间点开始记录数据。不过现在我们是从头开始,先不管这些细节。
2.每位学生平均花多长时间?
计算出队的人花费时间的平均数。需要记录每个出队的人花费的时间以及出队人数。
3.平均排队等待的人有多少?
需要理解这题里的 “平均” 是60分钟上的平均。因此只需记录每分钟排队人数,最后求平均数即可。
二、代码实现
1.学生的结构体
学生至少需要有三个属性:
1.选餐时长,范围是1~3分钟
2.入队时间,用于计算等待时间
3.开始选餐时间,用于判断学生是否应该出队
struct stu {
//int key;//标识码,可有可无
int select_time;//选餐时长
int create_time;//入队时间
int select_begin_time;//开始选餐时间
};
2.学生的随机生成
每个学生对象包含两个随机量: 入队时间 和 点餐时间
前者在方法被调用时传入,后者直接随机产生
struct stu randstu(int time_count)
{
struct stu* temp = (struct stu*)malloc(sizeof(struct stu));
if (temp) {
//srand((unsigned)time(NULL));
temp->select_time = rand() % 3 + 1;//随机一个点餐时间
temp->create_time = time_count;
temp->select_begin_time = -1;
return *temp;
}
else {
printf_s("wrong");
}
3.队列的模拟
队列模拟包含两部分:
1.队列
离队队列: 因为离队的人顺序不会变,可以直接作为数组使用
排队队列: 循环队列实现,因此还需要两个额外的下标记录head和tail
int queue_head = 0, queue_tail = 100;
struct stu stu_leave[100];//离队队列
struct stu stu_queue[101];//排队队列,长度100
2.出入队动作
入队: 实现是否入队,以及入队几人的逻辑
出队: 实现排头head是否出队的逻辑
//入队操作
void insert(int time_count)
{
/*特别声明:1.这里的233,107,523,229四个质数是我自己取的!!!取不同的值是会有不同结果的.
2.原因是题目中没有给定学生出现的概率在时间轴上的分布,也就是说学生到底在什么时间
会出现以及会出现多少个都是未知的.
3.但我们的目的只是用队列模拟排队,而不是研究概率问题,参数在具体问题中也可修改.*/
int insert_num = (rand() % 233 < 107 ? 0 : (rand() % 523 < 229 ? 1 : 2));//入队几人
while (insert_num-- > 0) {
//依次入队
if