假设银行有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
具体实现看代码注释,当一个人面临很多个窗口的wintime比他到达的时间少时,把这些窗口的wintime改成他到达的时间,这样在优先队列中会优先选择编号最小的。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#include<cstdlib>
using namespace std;
const int maxn = 105000;
int wintime[15] = {};//记录各窗口服务完客户后的时间,初始化为0
struct Guest{
int T;//到达时间
int P;//事务处理时间
}temp[maxn];//客户结构体
struct window{
int index;//编号
int count;//记录服务客户数量
}win[maxn];//窗口结构体
struct compare{
bool operator()(const int &x,const int &y) const {
if(wintime[x] != wintime[y]) return wintime[x] > wintime[y];//返回服务完客户后时间小的窗口
return x > y;//返回编号小的窗口
// if(wintime[x] == wintime[y]) return x > y;//返回编号小的窗口
// else return wintime[x] > wintime[y];//返回服务完客户后时间小的窗口
}
};//优先队列自定义优先规则,规定时间少窗户优先和编号小窗户优先
int main()
{
int N,K;
priority_queue<int,vector<int>,compare>Q;//优先队列Q
cin>>N;
int endtime = 0,maxtime = 0,waittime = 0;//定义最后完成时间、最长等待时间、等待时间的和
for(int i = 0;i < N;i++){//输入每一位客户的到达时间和处理时间
cin>>temp[i].T;
cin>>temp[i].P;
if(temp[i].P > 60) temp[i].P = 60;
}
cin>>K;
for(int i = 0;i < K;i++){//输入每一个窗口的编号、计数,把他们都入队
win[i].index = i;
win[i].count = 0;
Q.push(i);
}
for(int i = 0;i < N;i++){//大循环,求出等待时间的和、最长等待时间、最后完成时间
while(wintime[Q.top()] < temp[i].T){//这个while,当一个人面临很多个窗口的wintime比他到达的时间少时,把这些窗口的wintime改成他到达的时间,这样在优先队列中会优先选择编号最小的。
int ww = Q.top();
Q.pop();
wintime[ww] = temp[i].T;
Q.push(ww);
}
int ww = Q.top();//最优先的窗口出队
Q.pop();
win[ww].count++;//窗口计数
if(wintime[ww] > temp[i].T){//如果ww号窗口的wintime大于一个人的到达时间,那么这个人就需要等待
waittime += wintime[ww] - temp[i].T;//计算这个人的等待时间=窗口服务完客户后的时间-到达时间
maxtime = max(maxtime,wintime[ww] - temp[i].T);//实时更新最长等待时间
}
wintime[ww] = max(wintime[ww],temp[i].T) + temp[i].P;//针对不需要等待的人,wintime就为到达时间+处理时间,max选择了wintime[ww]是这个人刚好不需要排队的情况
endtime = max(endtime,wintime[ww]);//实时更新最后完成时间
Q.push(ww);//窗口入队
}
printf("%.1f %d %d\n",waittime*1.0/N,maxtime,endtime);//输出平均等待时间、最后完成时间、最长等待时间。
for(int i = 0;i < K;i++){//输出每个窗口服务客户的数目
if(i) printf(" ");
cout<<win[i].count;
}
printf("\n");
return 0;
}