题目大意:一个银行有K个窗口,可同时为K个客户办理业务,其余客户将在大厅等待,直到某一窗口的客户业务办理结束。求每位客户等待时长的平均值。题目给出n个客户的到达时间和办理业务所需时间,其中,在17:00:00以后到达的客户将无法办理业务,也不会计算等待时间,8:00:00前到达的客户将一直等到8:00:00再进行业务办理。且题目中保证不会有两个客户同时到达。
思路:将所有客户的时间转换为秒进行计算。通过优先队列来维护每个窗口的业务办理进程。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N=1e4+5;
const int ST=8*60*60;
const int EN=17*60*60;
struct Cust{
int st,ti,en,wai,flag;
} per[N];
struct Node{
int id,en;
Node(){}
Node(int id,int en): id(id),en(en){}
bool operator < (const Node &a)const{
if(en==a.en) return id>a.id;
return en>a.en;
}
};
bool cmp(const Cust &a,const Cust &b){
return a.st<b.st;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
int h,m,s;
scanf("%d:%d:%d%d",&h,&m,&s,&per[i].ti);
per[i].ti*=60;
per[i].st=h*60*60+m*60+s;
if(per[i].st>EN) per[i].flag=1;
else per[i].flag=0;
}
sort(per,per+n,cmp);
int cnt=0;
priority_queue<Node> q;
for(int i=0;i<k;i++)
if(cnt<n){
if(per[cnt].st<ST)
per[cnt].wai=ST-per[cnt].st;
per[cnt].en=per[cnt].st+per[cnt].wai+per[cnt].ti;
q.push(Node(cnt,per[cnt].en));
cnt++;
}
while(!q.empty()){
Node now=q.top(); q.pop();
if(cnt<n){
per[cnt].wai=max(0,per[now.id].en-per[cnt].st);
per[cnt].en=per[cnt].st+per[cnt].wai+per[cnt].ti;
q.push(Node(cnt,per[cnt].en));
cnt++;
}
}
int num=0,sum=0;
for(int i=0;i<n;i++)
if(per[i].flag==0){
sum+=per[i].wai;
num++;
}
printf("%.1lf\n",sum/60.0/num);
return 0;
}