Bootstrap

PTA 银行排队问题之单队列多窗口服务

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]);
	}
}
;