加载中...

银行排队

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;
}
posted @ 2022-08-23 11:27  英雄不问出处c  阅读(16)  评论(0编辑  收藏  举报