银行排队问题之单队列多窗口服务 (25分)(C语言)
假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。
本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间,并且统计每个窗口服务了多少名顾客。
输入格式: 输入第1行给出正整数N(≤1000),为顾客总人数;随后N行,每行给出一位顾客的到达时间T和事务处理时间P,并且假设输入数据已经按到达时间先后排好了顺序;最后一行给出正整数K(≤10),为开设的营业窗口数。这里假设每位顾客事务被处理的最长时间为60分钟。
输出格式: 在第一行中输出平均等待时间(输出到小数点后1位)、最长等待时间、最后完成时间,之间用1个空格分隔,行末不能有多余空格。
在第二行中按编号递增顺序输出每个窗口服务了多少名顾客,数字之间用1个空格分隔,行末不能有多余空格。
输入样例:
9 0 20 1 15 1 61 2 10 10 5 10 3 30 18 31 25 31 2 3
输出样例:
6.2 17 61 5 3 1
感谢浙江财经大学王瑞洲、周甄陶同学修正测试数据!
总体思路:某个顾客到达时,从左向右寻找要去办理事务的窗口,若发现有已经办理完或刚好有人办理完,就去此窗口办理,无等待时间。若每个窗口都有人,就选择最早结束的窗口,等待时间就是这个窗口结束时间减去到达时间。
代码:
#include <stdio.h> #include <stdlib.h> typedef struct customer{ int T,P; }*cust; void custQue(); int main() { custQue(); return 0; } void custQue() { int wait=0,sumWait =0,MaxWait =0; //time[100]数组存放办理时间,即某个窗口办完业务的时间 //num[100]存放某个窗口的人数 int time[100]={ 0},num[100]={ 0},j,maxFin; int n,i,m,min,pmin=0; cust cu; scanf("%d",&n); cu = (cust)malloc(sizeof(struct customer)*n); for(i=0;i<n;i++) { //输入数据时,满60设置为60 scanf("%d%d",&cu[i].T,&cu[i].P); if(cu[i].P>60) cu[i].P = 60; } scanf("%d",&m); for(i=0;i<n;i++){ //当有多个窗口可选择时,顾客选择编号最小的窗口 //printf("到达:%d 事务:%d ",cu[i].T,cu[i].P); min = time[0]; pmin = 0; for(j=1;j<m;j++){ if(min<=cu[i].T){ min = i; break; } if(min>time[j]) { min = time[j]; pmin = j; } } //所选窗口事务是否办理完成 if(time[pmin] < cu[i].T){ time[pmin] = cu[i].P+cu[i].T; num[pmin]++; }else{ wait = time[pmin] -cu[i].T; if(MaxWait<wait) MaxWait = wait; sumWait+=wait; time[pmin]+= cu[i].P; num[pmin]++; } } //寻找最大完成时间 maxFin = time[0]; for(i=1;i<m;i++){ if(maxFin<time[i]) maxFin = time[i]; } printf("%.1f %d %d ",1.0*sumWait/n,MaxWait,maxFin); for(i=0;i<m;i++){ if(!i) printf("%d",num[i]); else printf(" %d",num[i]); } }