顾客排队购买蛋挞问题(算法与数据结构设计)

news2024/10/6 21:20:30

课题内容和要求

顾客排队买蛋挞问题。有N个顾客排队,每人最多买M个。烘焙员每次烘焙1到K个蛋挞放入盘中,顾客只能购买盘中的蛋挞,未达到M个需重新排队。输出每个顾客购买情况和完成顺序。
例如——
输入:N=9,K=5;M=7
输出的购买情况为:

首次购买数量第二次购买数量第三次购买数量
顾客1151
顾客2214
顾客3322
顾客443
顾客552
顾客616
顾客7223
顾客8322
顾客943

购买到M个蛋挞的顾客的顺序为:4,5,6,9,1,2,3,7,8

数据结构说明

结构体Shop,存放商店营业信息,包括顾客数量N,蛋挞每次生产的上限K,每个顾客最多购买的数量M,以及每位顾客购买信息用结构体数组cu存放。数组result用于存放购买到M个蛋挞的顾客顺序,例如result[0]=i,表示顾客i第一个购买完M个蛋挞。list_col用于记录购买情况表的列数,控制最后输出购买情况的表头。

结构体Customer,存放顾客还需要购买蛋挞的数量(初始时需要购买数量M),顾客购买次数record,以及每次购买的记录以链表的形式按次序存储。

结构体Cal,存放顾客购买记录的链表结点,n表示该次购买的数量,next指向下一次购买记录结点。

算法设计

算法步骤:
(1)根据输入初始化shop当中的所有信息。
(2)初始化控制数组cu元素循环的下标cu_cal为0,初始化控制数组result下标的re_cal为0,标记flag初始化为0,蛋挞每次生产数量i初始化为0。
(3)若flag不为1,执行以下循环,直至flag=1。
a.i+1,若i>K重新置i=1,并将i加入到盘K_当中
b.通过循环判断顾客还需购买的数量mount是否为0,若为0表示购买完毕,数组cu下标cu_cal+1后对顾客数量N取模,遍历完数组cu直至找到一个还没购买完M个蛋挞的顾客,退出b步骤循环。该循环不会死循环,总能找到最后一个顾客未购买完M个蛋挞,并在后续步骤中将flag置为1,在下一轮大循环((3)步骤)中退出,不会再进到该循环。
c.判断盘中K_的数量是否大于顾客还需够买的数量mount,若mount大于K_则将mount的值减去K_的值,并添加该顾客的购买记录,置K_为0,接着判断该顾客的购买记录数record是否大于购买情况结果列数list_col,若大于则将record值赋值给list_col;若mount小于或等于K_,则将K_的值减去mount的值,并添加该顾客的购买记录,接着判断该顾客的购买记录数record是否大于购买情况结果列数list_col,若大于则将record值赋值给list_col,置该顾客的mount为0,此时该顾客已经购买完M个蛋挞,将该顾客的序号cu_cal加1后(加1后才是顾客真正的序号)赋值给购买顺序结果result[re_cal],re_cal加1使数组result下标后移。判断re_cal的值是否等于顾客数量N,若等于,表示所有顾客都已购买完M个蛋挞,置flag为1。
d.cu_cal加1并对N取模,使数组cu下标后移
(4)依据list_col值循环输出购买情况表头“第i+1次购买数量”
(5)依据顾客N值循环输出顾客的序号,并且遍历购买记录链表输出购买数量
(6)最后按顺序循环输出存放在数组result中顾客购买顺序

详细设计

程序包含文件shop_main.c、shop.h、shop.c

shop_main.c

#include <stdio.h>
#include <stdlib.h>
#include "shop.h"
int main()
{
    Shop *sh = (Shop*)malloc(sizeof(Shop));
    int N = 0;  // 顾客数量
    int K = 0;  // 商店生产蛋挞的上限
    int M = 0;  // 顾客需要购买的数量
    printf("蛋挞店\n");
    printf("请输入顾客数量:\n");
    scanf("%d",&N);
    printf("请输入商店生产蛋挞的上限:\n");
    scanf("%d",&K);
    printf("请输入顾客需要购买的数量:\n");
    scanf("%d",&M);
    Init_shop(sh,N,K,M);    // 调用函数初始化商店营业信息
    Shop_work(sh);      // 调用函数生成购买情况并输出
    printf("回车结束程序...\n");
    getchar();  // 将输入顾客需要购买的数量时按下的回车接收
    getchar();  // 等待输入回车结束程序运行
    free(sh);
}

shop.h

#ifndef __SHOP_H__
#define __SHOP_H__
typedef struct cal  // 存放顾客一次购买记录的结构体
{
    int n;  // 存放购买数量
    struct cal *next;   // 指向下一个结点的指针
}Cal;
typedef struct customer // 存放顾客购买信息的指针
{
    int mount;  // 存放还需要购买的数量
    int record; // 存放购买次数
    Cal *first; // 存放购买记录的链表头指针
}Customer;
typedef struct shop // 商店营业信息
{
    Customer *cu;   // 存放顾客信息的数组头指针
    int *result;    // 将已经购买到M个蛋挞顾客按顺序存入数组
    int list_col;   // 记录生成结果表的列数,用于构造结果表
    int N; // 顾客数量
    int K;  // 生产蛋挞的上限
    int K_; // 盘中被购买后剩余的蛋挞数量
    int M;  // 顾客需要购买蛋挞的数量
}Shop;
void Init_shop(Shop *shop,int N, int K, int M); // 商店初始化
void Creat_cal(Customer *cu, int n);    // 购买记录结点创建
void Shop_work(Shop *shop); // 商店程序运行
#endif

shop.c

#include "shop.h"
#include <stdio.h>
#include <stdlib.h>
/**
 * @brief 商店初始化
 * @param shop 指向商店营业信息的指针
 * @param N 顾客数量
 * @param K 商店生产蛋挞的上限
 * @param M 顾客需要购买蛋挞的数量
 * @return void
*/
void Init_shop(Shop *shop,int N, int K, int M)
{
    shop->list_col = 0; // 初始化购买情况结果列数为0
    shop->N = N;
    shop->cu = (Customer*)malloc(N*sizeof(Customer));   // 动态申请存顾客信息的数组空间
    shop->result = (int*)malloc(N*sizeof(int)); // 动态申请存放顾客编号
    if(!shop->cu&&!shop->result)
    {
        printf("申请空间失败————顾客数组,购买顺序\n");
    }
    for(int i = 0;i<N;i++)  // 初始化每个顾客信息
    {
        shop->cu[i].mount = M;
        shop->cu[i].first = NULL;
        shop->cu[i].record = 0;
        shop->result[i] = 0;
    }
    shop->K = K;
    shop->K_ = 0;
    shop->M = M;
}
/**
 * @brief 购买记录结点创建
 * @param cu 指向顾客信息的指针
 * @param n 该次购买蛋挞的数量
 * @return void
*/
void Creat_cal(Customer *cu, int n)
{
    if(cu->first==NULL) // 当没有购买记录时创建第一次购买记录
    {
        cu->first = (Cal*)malloc(sizeof(Cal));
        if(!cu->first)
        {
            printf("申请空间失败————购买记录");
        }
        cu->first->n = n;
        cu->record+=1;
        cu->first->next = NULL;
        return;
    }
    Cal *p = cu->first;
    for(;p->next; p=p->next);  // 将p指向最后一个不为空的结点,链表元素尾插
    p->next = (Cal*)malloc(sizeof(Cal));
    if(!p->next)
    {
        printf("申请空间失败————购买记录");
    }
    p->next->n = n;
    cu->record += 1;
    p->next->next = NULL;
}
/**
 * @brief 商店程序运行
 * @param shop 指向商店营业信息的指针
 * @return void
*/
void Shop_work(Shop *shop)
{
    int cu_cal = 0; // 数组下标,用于循环顾客排队购买蛋挞
    int re_cal = 0; // 数组下标,用于result数组的计数,每当一个顾客购买完所需的蛋挞,+1
    int flag = 0;   // 标记,用于提前退出循环
    int i = 0;  // 蛋挞生产计数1~K
    while(!flag)
    {
        i++;
        if(i>shop->K)   // 当蛋挞生产计数大于K时,重新置为1开始累加
        {
            i=1;
        }
        shop->K_+=i;    // 将该次生产的蛋挞数加入到被购买后剩余的蛋挞数量中
        while(shop->cu[cu_cal].mount==0)    // 判断顾客是否购买完蛋挞,如果购买完,将数组下标向后移
        {
            // 该循环不会死循环,总能找到最后一个顾客未购买完M个蛋塔,
            // 并在后续步骤中将flag置为1,在下一轮大循环中退出,不会再进到该循环
            cu_cal = (cu_cal+1)%shop->N;   // 数组下标后移
        }
        if(shop->cu[cu_cal].mount>shop->K_) // 顾客还需要购买的数量大于盘中剩余数量
        {
            shop->cu[cu_cal].mount-=shop->K_;
            Creat_cal(&(shop->cu[cu_cal]),shop->K_);    // 调用函数创建购买记录结点
            shop->K_ = 0;
            if(shop->list_col<(shop->cu[cu_cal].record))    // 如果顾客的购买记录数大于结果表的列数,更新列数
            {
                shop->list_col = shop->cu[cu_cal].record;
            }
        }
        else    // 顾客还需要购买的数量小于或等于盘中剩余数量
        {
            shop->K_ -= shop->cu[cu_cal].mount;
            Creat_cal(&(shop->cu[cu_cal]),shop->cu[cu_cal].mount);     // 调用函数创建购买记录结点
            if(shop->list_col<(shop->cu[cu_cal].record))
            {
                shop->list_col = shop->cu[cu_cal].record;
            }
            shop->cu[cu_cal].mount = 0;
            shop->result[re_cal] = cu_cal+1;    // 顾客所需数量已足够,将顾客编号记录在数组中
            re_cal +=1; // 数组下标后移
            if(re_cal==shop->N) // 如果re_cal等于顾客数量,则表示所有顾客都购买完蛋挞,置flag标志位为1
            {
                flag = 1;
            }
        }
        cu_cal = (cu_cal+1)%shop->N;    // 数组下标后移
    }
    // 将购买情况输出
    printf("购买情况如下:\n");
    printf("          ");
    for(i = 0;i<shop->list_col;i++) // 输出表头
    {
        printf("第%d次购买数量 ",i+1);
    }
    printf("\n");
    for(i = 0;i<shop->N;i++)
    {
        Cal *p = shop->cu[i].first;
        printf("顾客%2d",i+1);
        for(;p;p = p->next) // 将每个顾客购买信息一行一行的输出
        {
            printf("%13d",p->n);
        }
        printf("\n");
    }
    printf("购买到%d个蛋挞的顾客的顺序为:",shop->M);
    for(i = 0;i<shop->N;i++)
    {
        printf("顾客%d ",shop->result[i]);
    }
    printf("\n");
}

测试数据及其结果分析

运行结果1(题目例子):
在这里插入图片描述
运行结果2:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1908033.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

游戏软件缺少d3dx9_42.dll怎么修复?五种方法助你轻松解决

D3DX9_42.dll的丢失是一种常见的操作系统异常问题&#xff0c;由于日常使用电脑时的不当操作&#xff0c;可能会导致一些dll文件的丢失&#xff0c;D3DX9_42.dll就是其中之一。对于这种情况&#xff0c;我们可以通过谨慎的修复来解决。以下是一种科学的解决D3DX9_42.dll丢失的方…

【面试题】串联探针和旁挂探针有什么区别?

在网络安全领域中&#xff0c;串联探针和旁挂探针&#xff08;通常也被称为旁路探针&#xff09;是两种不同部署方式的监控设备&#xff0c;它们各自具有独特的特性和应用场景。以下是它们之间的主要区别&#xff1a; 部署方式 串联探针&#xff1a;串联探针一般通过网关或者…

刷题(day01)

1、leetcode485.最大连续1的个数 给定一个二进制数组 nums &#xff0c; 计算其中最大连续 1 的个数。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,0,1,1,1] 输出&#xff1a;3 解释&#xff1a;开头的两位和最后的三位都是连续 1 &#xff0c;所以最大连续 1 的个数是 3.…

Linux环境部署Python Web服务

“姑娘&#xff0c;再见面就要靠运气了&#xff0c;可别装作不认识&#xff0c;那句“好久不见”可干万别打颤…” 将使用 Python 编写的后端 API 部署到 Linux 环境中&#xff0c;可以按照以下详细步骤操作。本文将涵盖环境准备、API 编写、使用 Gunicorn 作为 WSGI 服务器、配…

C#反射基本应用

1、反射 反射是.NET Framework的一个特性&#xff0c;它允许在运行时获取类型的信息以及动态创建对象&#xff0c;调用方法&#xff0c;以及访问字段和属性。 2、代码 using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy…

运维锅总详解系统设计原则

本文对CAP、BASE、ACID、SOLID 原则、12-Factor 应用方法论等12种系统设计原则进行分析举例&#xff0c;希望对您在进行系统设计、理解系统运行背后遵循的原理有所帮助&#xff01; 一、CAP、BASE、ACID简介 以下是 ACID、CAP 和 BASE 系统设计原则的详细说明及其应用举例&am…

【小鸡案例】表单focus和blur事件用法

input中有2个属性&#xff0c;一个是focus获取焦点&#xff0c;一个是blur失去焦点。获取焦点就是我们点击输入框时输入框被选中&#xff1b;失去焦点即点击输入框以外的区域&#xff0c;今天就用这两种属性做一个点击输入框的动画效果。 先写个输入框&#xff0c;代码如下&am…

如何使用 pytorch 创建一个神经网络

我已发布在&#xff1a;如何使用 pytorch 创建一个神经网络 SapientialM.Github.io 构建神经网络 1 导入所需包 import os import torch from torch import nn from torch.utils.data import DataLoader from torchvision import datasets, transforms2 检查GPU是否可用 dev…

Nacos 进阶篇---集群:选举心跳健康检查劳动者(九)

一、引言 本章将是我们第二阶段&#xff0c;开始学习集群模式下&#xff0c;Nacos 是怎么去操作的 &#xff1f; 本章重点&#xff1a; 在Nacos服务端当中&#xff0c;会去开启健康心跳检查定时任务。如果是在Nacos集群下&#xff0c;大家思考一下&#xff0c;有没有必要所有的…

[FreeRTOS 基础知识] 任务通知 概念

文章目录 任务通知 定义FreeRTOS 任务通知机制 任务通知 定义 实时操作系统&#xff08;RTOS&#xff09;的任务通知机制是一种用于任务间通信和同步的机制。在FreeRTOS中&#xff0c;任务通知允许一个任务向另一个任务发送通知&#xff0c;表明某个事件已经发生或者某些条件已…

鸿蒙语言基础类库:【@ohos.url (URL字符串解析)】

URL字符串解析 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 导入…

【9-2:RPC设计】

RPC 1. 基础1.1 定义&特点1.2 具体实现框架1.3 应用场景2. RPC的关键技术点&一次调用rpc流程2.1 RPC流程流程两个网络模块如何连接的呢?其它特性RPC优势2.2 序列化技术序列化方式PRC如何选择序列化框架考虑因素2.3 应用层的通信协议-http什么是IO操作系统的IO模型有哪…

【Excel技巧大揭秘】如何轻松绕过Excel工作表保护密码?

在日常工作中&#xff0c;我们时常会遇到设置了工作表保护的Excel文件&#xff0c;本意是为了数据安全&#xff0c;但偶尔在急需编辑文件时却遗忘了密码&#xff0c;这无疑让人感到头疼。面对这样的困境&#xff0c;别担心&#xff0c;本文将为您揭秘两种高效解决策略&#xff…

go语言day12 包 init() time包 file包

包 包中的 结构体 及结构体属性 方法 都可以通过设置首字母大小写来实现权限访问&#xff0c;首字母大写任何包中都可以访问&#xff0c;首字母小写只在同包中可以访问。 再导入包go文件时&#xff0c;可以给.go文件取别名。 在导入的包名前加入 _ 意思是调用该包的初始…

OpenHarmony 入门——单元测试UnitTest快速入门

引言 OpenHarmony 的单元测试&#xff08;UnitTest&#xff09;是一个关键的软件开发过程&#xff0c;它确保代码的各个部分能够按预期工作&#xff0c;OpenHarmony的测试框架中提供了很多种的单元测试&#xff0c;今天简单介绍下UnitTest 类型的TDD测试。 OpenHarmony 的TDD …

尚品汇-(十五)

&#xff08;1&#xff09;快速入门 SpringBoot形式创建 Maven形式创建&#xff1a; 加入依赖&#xff1a; 创建启动类&#xff1a; 设置头文件 就想Jsp的<%Page %>一样 &#xff0c;Thymeleaf的也要引入标签规范。不加这个虽然不影响程序运行&#xff0c;但是你的idea…

【楚怡杯】职业院校技能大赛 “Python程序开发”赛项样题三

Python程序开发实训 &#xff08;时量&#xff1a;240分钟&#xff09; 中国XX 实训说明 注意事项 1. 请根据提供的实训环境&#xff0c;检查所列的硬件设备、软件清单、材料清单是否齐全&#xff0c;计算机设备是否能正常使用。 2. 实训结束前&#xff0c;在实训平台提供的…

vue项目实现堆叠卡片拖动切换效果

实际效果 实现流程 1. 实现卡片位置堆叠 将父元素的 position 设置成relative &#xff0c;卡片的position 设置成 absolute 即可。 2. 消除图片的移动 如果卡片上有图片&#xff0c;默认拖动的时候就会导致像上图一样变成了选中图片移动&#xff0c;从而没法触发拖动事件。消…

用Vue3和Plotly.js绘制交互式3D小提琴图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Vue 中使用 Plotly.js 创建小提琴图 应用场景介绍 小提琴图是一种统计图&#xff0c;用于显示数据的分布和中心趋势。它结合了箱线图和密度图的特点&#xff0c;可以直观地展示数据的分散性和形状。 代码基本…

python如何进行pip换源

hello&#xff0c;大家好&#xff0c;我是一名测试开发工程师&#xff0c;至今已在自动化测试领域深耕9个年头&#xff0c;现已将本人实战多年的多终端自动化测试框架【wyTest】开源啦&#xff0c;请大家快来体验并关注我吧。 Python的包管理工具pip是开发者必备的利器之一。然…