思路:1:用合适的存储结构表示顾客和窗口
2:同样用前缀和思想来表示顾客在经过排队到窗口的等待时间。
难点:1:用结点数组表示顾客并且在结点中进行operator为排序做准备。
2:用小顶堆表示窗口,每个结点表示窗口的空闲时间。
3:用秒表示每个时间到00:00:00的间隔;再用前缀和思想计算两个人之间的时间。
4:对每个人来说{1:通过比较一个人的到达时间和窗口的空闲时间来分配一个空窗口;2:更新该窗口的下一个空闲时间}
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 10010,M=100;
struct person {
int start_time;
int serve_time;
bool operator<(const person&t)const {
return start_time < t.start_time;
}
}persons[N];
int main()
{
int n, m;
cin >> n >> m;
int hour, minute, second,serve_time;
for (int i = 0; i < n; i++)
{
scanf("%d:%d:%d %d", &hour, &minute, &second, &serve_time);
serve_time = min(serve_time, 60);
persons[i] = { hour * 3600 + minute * 60 + second,serve_time*60};
}
sort(persons, persons + n);
priority_queue<int, vector<int>, greater<int>>windows;
for (int i = 0; i < m; i++)
windows.push(8 * 3600);
int sum = 0, cnt = 0;
for (int i=0;i<n;i++)
{
auto person=persons[i];
auto w = windows.top();
windows.pop();
if (person.start_time > 17 * 3600)
break;
int start_time = max(w, person.start_time);
sum += start_time - person.start_time;
cnt++;
windows.push(start_time + person.serve_time);
}
printf("%.1lf\n", (double)sum / cnt / 60);
return 0;
}