既然是队列的应用,队列的基本操作不能少。队列的初始化、求队列长度、入队、出队、取队头元素啥的是基础咯。
这道题看起来好像有点点复杂,但是动动手画画找找规律,很容易发现规律的~
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;
}