scau 8590 队列的应用——银行客户平均等待时间

       既然是队列的应用,队列的基本操作不能少。队列的初始化、求队列长度、入队、出队、取队头元素啥的是基础咯。

       这道题看起来好像有点点复杂,但是动动手画画找找规律,很容易发现规律的~

        n个客户的平均等待时间,就是n个客户的等待时间除以n,这个好理解吧。然后,等待时间怎么求呢?以输入样例为例,第一个客户1点到的,他要办理3个小时(也就是办到4点),而第二个客户2点就到了,那他就要等2个小时,第二个客户办理1个小时(也就是办到5点),而第三个客户3点就来了,那第三个客户也要等2个小时,再办理5个小时的业务。总共的等待时间就是4个小时啦,有三个客户,那么平均等待时间就为4/3=1.33。

       经过上面的一波分析,我们主要需要四个变量一个等待时间,一个离开时间,一个到达时间,一个办理时间(前面两个是中间处理变量,后面两个是题目要求输入的变量)。不难发现,一个客户的等待时间=上个客户的离开时间-该客户的到达时间而该客户的离开时间=上个客户的离开时间+该客户的办理时间。再把每个客户的等待时间写进队列即可。最后遍历队列求和再除以客户人数就能达到目标了。

       第一个客户的等待时间为0,把第一个单独拿出来。不过还有一点需要注意的是,当上个客户办理完业务离开后,下一个客户还没来,那么下一个客户的等待时间也是0哦。这是就要对等待时间做一个判断了。一个客户的等待时间(=上个客户的离开时间-该客户的到达时间)为负数,就说明该客户在上一个客户离开后还没有来,就把他的等待时间置为0。

下面是全部代码。

#include <cstdio>
#include <iostream>
#include <cstdlib>
#define OK 1
#define ERROR 0
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int QElemType;
#define MAXQSIZE 100 // 最大队列长度(对于循环队列,最大队列长度要减1)

using namespace std;

typedef struct
{
    QElemType *base; // 初始化的动态分配存储空间
    int front; // 头指针,若队列不空,指向队列头元素
    int rear; // 尾指针,若队列不空,指向队列尾元素的下一个位置
} SqQueue;

Status InitQueue(SqQueue &Q)
{
// 构造一个空队列Q,该队列预定义大小为MAXQSIZE
// 请补全代码
    Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
    Q.front=Q.rear=0;
    return OK;

}

Status EnQueue(SqQueue &Q,QElemType e)
{
// 插入元素e为Q的新的队尾元素
// 请补全代码
    if((Q.rear+1)%MAXQSIZE==Q.front)
    {
        return ERROR;
    }
    Q.base[Q.rear]=e;
    Q.rear=(Q.rear+1)%MAXQSIZE;
    return OK;

}

Status DeQueue(SqQueue &Q, QElemType &e)
{
// 若队列不空, 则删除Q的队头元素, 用e返回其值, 并返回OK; 否则返回ERROR
// 请补全代码
    if(Q.rear==Q.front)
        return ERROR;
    e=Q.base[Q.front];
    Q.front=(Q.front+1)%MAXQSIZE;
    return OK;
}

Status GetHead(SqQueue Q, QElemType &e)
{
// 若队列不空,则用e返回队头元素,并返回OK,否则返回ERROR
// 请补全代码
    if(Q.rear==Q.front)
        return ERROR;
    e=Q.base[Q.front];
    return OK;

}

int QueueLength(SqQueue Q)
{
// 返回Q的元素个数
// 请补全代码
    return abs(Q.front-Q.rear);
}

double QueueTraverse(SqQueue Q)
{
// 若队列不空,则从队头到队尾依次输出各个队列元素,并返回OK;否则返回ERROR.
    int i;
    double total = 0;
    i=Q.front;
    if(i==Q.rear)printf("The Queue is Empty!");  //请填空
    else
    {
        while(i!=Q.rear)     //请填空
        {
            // cout << Q.base[i];
            total+=Q.base[i];
            i+=1;
        }
    }
    // cout << total << endl;
    return total;
}

int main()
{
    double res;//等待时间
    int leave;//离开时间
    int stay;//等待时间
    SqQueue Q;
    InitQueue(Q);//初始化
    int n;
    scanf("%d",&n);//n个客户
    int a,b;
    scanf("%d %d",&a,&b);//第一个客户的到达时间和办理业务的时间
    EnQueue(Q,0);//第一个客户的等待时间为0
    leave=a+b;//离开时间=到达时间+办理时间
    for(int k=0; k<n-1; k++)
    {
        scanf("%d %d",&a,&b);//下一个客户的到达时间和办理时间
        stay=leave-a;//等待时间=上一个客户的离开时间-该客户的到达时间
        //这里需要注意stay小于0的情况
        if(stay<0)//如果上一个客户走了,下一个客户还没来
        {
            stay=0;//那么当前客户的等待时间为0
            leave=a+b;//离开时间=到达时间+办理时间
        }
        else
        {
            leave=leave+b;//否则,离开时间=上一个客户的离开时间+当前客户的办理时间
        }
        EnQueue(Q,stay);//把等待时间写进队列
    }
    res=QueueTraverse(Q)/(n);
    printf("%.2f",res);
    return 0;
}

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值