银行排队
https://www.acwing.com/problem/content/1496/
思路:
窗口问题的核心一般都是用小根堆维护,以小根堆为核心,切合实际情况。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 10010, M = 110;
int n, m;
struct Person
{
int arrive_time;
int service_time;
bool operator< (const Person& t) const // 按到达时间排序
{
return arrive_time < t.arrive_time;
}
}persons[N];
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
{
int hour, minute, second, service_time;
scanf("%d:%d:%d %d", &hour, &minute, &second, &service_time);
service_time = min(service_time, 60);
persons[i] = {hour * 3600 + minute * 60 + second, service_time * 60};
}
priority_queue<int, vector<int>, greater<int>> windows;
for (int i = 0; i < m; i ++ ) windows.push(8 * 3600); // 先把m个窗口安排好
sort(persons, persons + n);
int sum = 0, cnt = 0;
for (int i = 0; i < n; i ++ )
{
auto person = persons[i];
int w = windows.top();
windows.pop();
if (person.arrive_time > 17 * 3600) break; // 来晚了,则忽略
int start_time = max(person.arrive_time, w);
sum += start_time - person.arrive_time;
cnt ++ ;
windows.push(start_time + person.service_time);
}
printf("%.1lf\n", (double)sum / cnt / 60);
return 0;
}