题目分析
客户数据用什么存呢?
好吧,还是用结构体。
结构体里面存什么呢?
到达时间 和服务时间。
窗口怎么存呢?
将窗口的开始服务时间从小到大存,自然想到小根堆。
priority_queue<int, vector<int> , greater<int> > windows;
对于每个顾客:
1.找时间最早的窗口
2.将该人安排到该窗口 :累加等待时间(开始服务的时间 - 到达的时间),当前窗口新的结束时间是什么呢? 自己的结束时间+ 要服务顾客的服务时间,这里即为更新窗口.
ac代码
#include<bits/stdc++.h>
using namespace std;
const int N =1e4+10;
int n,k; // k表示窗口数量
//等待时间 = 结束时间 - 到来的时间
struct Person{
int arriveTime;
int serveTime;
bool operator<(const Person& a)const{
return arriveTime<a.arriveTime;
}
}person[N]; //结构体数组
int main(){
cin>>n>>k;
double res = 0;
int hour,minute,second, serveTime;
//读入所有客户
for(int i=0;i<n;i++){
scanf("%d:%d:%d %d",&hour,&minute, &second, & serveTime);
serveTime = min(serveTime , 60);
person[i] = {hour * 3600 + minute * 60 + second , serveTime* 60}; //时间统一成秒
}
priority_queue<int ,vector<int> ,greater<int>> windows; // 小根堆
//预处理窗口:存窗口的开始时间
for(int i=0;i<k;i++) windows.push(8*3600); //窗口开始服务时间,从8点钟开始服务, 转换成秒
//按到达时间从早到晚排序
sort(person, person+n);
int sum=0 , cnt =0;
for(int i =0 ;i< n; i++){
auto p = person[i];
//取出最早空闲的窗口
int w =windows.top();
windows.pop();
if(p.arriveTime > 17*3600) break; //谁来晚了,忽略之。
//某位顾客开始业务的时间:来早了没有空闲窗口,开始时间是窗口空闲时间;来晚了但有窗口空闲,开始时间是到达时间
//即两者取最大值
int startTime = max(p.arriveTime , w); //两种情况:有空闲窗口或者窗口有人
sum+= startTime - p.arriveTime; //累加等待时间
cnt ++; //可以被服务的人数
windows.push(startTime +p.serveTime); //更新窗口:服务完一个客户后开始的时间
}
printf("%.1lf\n",(double)sum/cnt/60);
}