餐厅【候桌问题】(链表模拟队列)

289 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

说在前面

🎈今天给大家带来的是算法练习,题目为"餐厅【候桌问题】"。

问题描述

在小餐馆里,有几张双人餐桌,四人餐桌和六人餐桌。应将一个用餐者或两个用餐者安排在一个双人餐桌上,三个或四个用餐者应安排在一个四人餐桌上,五个或六个用餐者应安排一个六人餐桌 。

餐厅供应美味佳肴,很多人都喜欢在这里用餐。每天午餐时间到来,餐厅通常都是用餐者。如果没有合适的餐桌就餐,他们必须等到合适的餐桌。如果超过半小时,他们将前往另一家餐馆。

现在给出一天即将到来的用餐者名单,请计算有多少用餐者在此餐厅用餐。您可以假设每个用餐者坐下来离开餐厅需要半个小时。
输入

有几个测试用例。每个案例的第一行包含由空格分隔的正整数,ABCABC> 0A + B + C <= 100),它们是双座位餐桌的数量,四个座位的餐桌和六个座位的餐桌数量。从第二行开始,表示到来的一组用餐者,每行包含两个整数,TN0 <N <= 6),表示该组用餐者的到达时间和数量。到达时间Ť由HHMM表示,并且在08:0022:00之间固定(餐厅在23:00关闭)列表按每个组的到达时间按升序排序,您可以假设没有组同时到达。每个测试用例以“#”行结束。
A = B = C = 0的测试用例结束输入。

输出

对于每个测试用例,您应该输出一个整数,即在餐厅以分开的线路吃食物的食客总数。

**输入样例 1 **

1 1 1
10:40 1
10:50 2
11:00 4
#
1 1 1
10:40 1
10:50 2
11:00 2
#
1 2 1
10:30 1
10:40 3
10:50 2
11:00 1
11:20 5
#
0 0 0

输出样例 1

7
3
12

思路分析

读完题目后,我们不难看出,这道题目我们可以用队列来解题,这里我用链表来模拟队列。

按照我们平时吃饭的经验,我们可以知道进餐馆后主要有以下几种情况:

1、餐馆里都是空桌,我们可以直接上桌点菜

2、餐馆里有人,都还有空桌,我们也可以直接上桌点菜

3、餐馆里暂时没有空余的位置,所以我们需要等,我们会等最快吃完的那一桌吃完,而这里又分两种情况

(1)我们又足够的时间等最快的那一桌吃完,所以我们等

(2)我们觉得要等太久,所以就不等了

下面我们结合题目给出的样例分析一下:

(1)

1 1 1

10:40 1

10:50 2

11:00 4

image.png 这一例子的流程如上图,所有人都可以吃上饭,我们只需要把上了桌的客人的人数全部加上(即右边的数字),便可得出结果为7。接下来让我们再看看另一种情况:

(2)

1 1 1

10:40 1

10:50 2

11:00 2

还是双人桌、四人桌、六人桌各有一张

1650377275(1).png 从上图可以看出第二批客人和第三批客人都需要等待,当第一批客人吃完的时候,第二批客人还在等,所以第二批就可以直接上桌了,而第三批客人则还需要等第二批的客人吃完,最后等了半个小时第二批客人还没有吃完,所以第三批客人就走了。所以可以吃上饭的只有前面两批客人,此时我们讲右边的数据加起来就是答案了。

经过分析,我们知道我们主要要解决以下问题:

如何判断客人来的时候需要等多久才能吃上饭,这里我用了一个函数来判断,代码如下:

int judg(int hh,int mm,int h,int m){
 
//h:m为当前餐馆里最早来的那批客人的上桌时间
    //计算第一批客人离开时间 
    m +=30;
    if(m >= 60){
        h++;
        m %= 60;
    }
    //离开时间早于来客时间 ,来客直接上桌 
    if(hh > h || (hh == h && mm >= m)) return 1;
    //离开时间晚于来客时间,来客等待
    mm += 30;
    if(mm >= 60){
        hh++;
        mm %= 60;
    } 
    //可以等到
    if(hh > h || (hh == h && mm >= m)) return 2;
    //等不到 
   return 0;
}

如何表示各种桌子的使用情况

  • (1)定义桌子结构体
struct desk{
    int HH;
    int MM;
    struct desk* p_next;
}; 
  • (2)定义双人桌的头和尾
struct desk* t_head = NULL;
struct desk* t_tail = NULL;
  • (3)记录双人桌的用餐情况
//双人桌用餐 
    if(n <= 2){
        if(t_head == NULL||t_tail == NULL){
            t_head = node;
            t_tail = node; 
            A--;
            return n;
        }
        else{
            //判断是否还有空桌
            if(A > 0){
                t_tail->p_next = node;
                t_tail = node;
                A--;
                return n;
            }
            
            if(judg(HH,MM,t_head->HH,t_head->MM) >= 1){
                if(judg(HH,MM,t_head->HH,t_head->MM) == 2){
                    int h = t_head->HH;
                    int m = t_head->MM;
                    m += 30;
                    if(m>=60){
                        h++;
                        m%=60;
                    }
                    node->HH = h;
                    node->MM = m;
                }
                t_tail->p_next = node;
                t_tail = node;
                t_head = t_head->p_next;
                return n;
            }
            return 0;
        }    
    }

另外四人桌和六人桌我也用了同样的方法,就不一一说明了。

AC代码

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include <stdlib.h>
 
int A,B,C;
//定义桌子结构体
struct desk{
    int HH;
    int MM;
    struct desk* p_next;
}; 
//两人桌 
struct desk* t_head = NULL;
struct desk* t_tail = NULL;
//四人桌 
struct desk* f_head = NULL;
struct desk* f_tail = NULL;
//六人桌 
struct desk* s_head = NULL;
struct desk* s_tail = NULL;
 
int judg(int hh,int mm,int h,int m){
    //计算第一批客人离开时间 
    m +=30;
    if(m >= 60){
        h++;
        m %= 60;
    }
    //离开时间早于来客时间 ,来客直接上桌 
    if(hh > h || (hh == h && mm >= m)) return 1;
    //离开时间晚于来客时间,来客等待
    mm += 30;
    if(mm >= 60){
        hh++;
        mm %= 60;
    } 
    //可以等到
    if(hh > h || (hh == h && mm >= m)) return 2;
    //等不到 
    return 0;
}
 
//创建链表(客人用餐)
int addNode(int n,int HH,int MM){
    struct desk* node = (struct desk*)malloc(sizeof(struct desk));
    node->HH = HH;
    node->MM = MM;
    node->p_next = NULL;

    //双人桌用餐 
    if(n <= 2){
        if(t_head == NULL||t_tail == NULL){
            t_head = node;
            t_tail = node; 
            A--;
            return n;
        }
        else{
            if(A > 0){
                t_tail->p_next = node;
                t_tail = node;
                A--;
                return n;
            }
            if(judg(HH,MM,t_head->HH,t_head->MM) >= 1){
                if(judg(HH,MM,t_head->HH,t_head->MM) == 2){
                    int h = t_head->HH;
                    int m = t_head->MM;
                    m += 30;
                    if(m>=60){
                        h++;
                        m%=60;
                    }
                    node->HH = h;
                    node->MM = m;
                }
                t_tail->p_next = node;
                t_tail = node;
                t_head = t_head->p_next;
                return n;
            }
            return 0;
        }	
    }

    //四人桌用餐 
    else if(n <= 4){
        if(f_head == NULL||f_tail == NULL){
            f_head = node;
            f_tail = node; 
            B--;
            return n;
        }
        else{
            if(B > 0){
                    f_tail->p_next = node;
                    f_tail = node;
                    B--;
                    return n;
            }

            if(judg(HH,MM,f_head->HH,f_head->MM) >= 1){
                if(judg(HH,MM,f_head->HH,f_head->MM) == 2){
                    int h = f_head->HH;
                    int m = f_head->MM;
                    m += 30;
                    if(m>=60){
                        h++;
                        m%=60;
                    }
                    node->HH = h;
                    node->MM = m;
                }
                f_tail->p_next = node;
                f_tail = node;
                f_head = f_head->p_next;
                return n;
            }
            return 0;
        }
    }

    //六人桌用餐 
    else{
        if(s_head == NULL||s_tail == NULL){
            s_head = node;
            s_tail = node; 
            C--;
            return n;
        }
        else{
            if(C > 0){
                s_tail->p_next = node;
                s_tail = node;
                C--;
                return n;
            }
            if(judg(HH,MM,s_head->HH,s_head->MM) >= 1){
                if(judg(HH,MM,s_head->HH,s_head->MM) == 2){
                    int h = s_head->HH;
                    int m = s_head->MM;
                    m += 30;
                    if(m>=60){
                        h++;
                        m%=60;
                    }
                    node->HH = h;
                    node->MM = m;
                }
                s_tail->p_next = node;
                s_tail = node;
                s_head = s_head->p_next;
                return n;
            }
            return 0;
        }
    }
return 0;
} 
 
int main()
{
	while(1){
		scanf("%d %d %d",&A,&B,&C);
		if((A == 0) && (B == 0) && (C == 0)) break;
		int sum = 0;
		int HH=0,MM=0,N=0,i=0;
		while(scanf("%d:%d %d",&HH,&MM,&N)!=EOF){
				char ch=getchar();
				if(ch=='#')
					break;
				sum += addNode(N,HH,MM);	
			}
			printf("%d\n",sum);
			sum = 0;
			//双人桌 
			t_head = NULL;
			t_tail = NULL;
			//四人桌 
			f_head = NULL;
			f_tail = NULL;
			//六人桌 
			s_head = NULL;
			s_tail = NULL;
		}
	
	return 0;
 } 

说在后面

🎉这里是JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,平时也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。