PTA 银行排队问题之单队列多窗口服务
题目描述:
假设银行有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
思路:
本题目基础题目:PTA 银行业务队列简单模拟
本题与银行业务的简单模拟都使用队列进行处理,但是在本题中,为一个多列,多个窗口。而且本题需要考虑客户到达时间T和事务处理时间P,但是好在客户的到达时间已经有序,故在实现时按照时间顺序进行树立即可。
首先读数据,在具体模拟是需要记录截止当前时间第K个窗口的客户已经处理了多久,当本窗口的客户书屋处理时间已到,则需从队列中再叫一个,而其他窗口对应的时间相应减少。
本题需要注意有可能在中间时间段所有窗口都无客户进行处理业务。
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
using namespace std;
int peo[1100][3];
int num[20];//记录各窗口完成多少人
int ck[20];//记录各各窗口到什么时间完成
int ckm;//记录当前工作的窗口
int dqtime;
int main(){
int n, k, que;
int dd_max = 0, dd_sum = 0, timesum = 0;
int t = 0;
scanf("%d",&n);
que = n;
for( int i=0; i<n; i++){
int a,b;
scanf("%d%d",&a,&b);
peo[i][0] = a;
if( b <= 60 ) peo[i][1] = b;
else peo[i][1] = 60;
}
int p = 0;
scanf("%d",&k);
for( dqtime=0; p<n; dqtime++){
if(dqtime != 0)
for(int i=0; i<k; i++)
if(ck[i] == dqtime) ckm--;
while( ckm<k && p<n && peo[p][0]<=dqtime){
for(int i=0; i<k; i++){
if( ck[i] <= dqtime ){
num[i]++; ckm++;
ck[i] = dqtime+peo[p][1];
peo[p][2] = dqtime-peo[p][0];
p++;
break;
}
}
}
if( p >= n )break;
}
for(int i=0; i<k; i++)
if( ck[i] >= timesum ) timesum = ck[i];
for(int i=0; i<n; i++){
dd_sum += peo[i][2];
if(peo[i][2] >= dd_max) dd_max = peo[i][2];
}
double ave = dd_sum*1.0/n;
printf("%.1lf %d %d\n",ave,dd_max,timesum);
for(int i=0; i<k; i++){
if( i ) printf(" ");
printf("%d",num[i]);
}
}