题目


解法1

点击查看代码
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

int time2int(int hh, int mm, int ss) {
    return hh * 3600 + mm * 60 + ss;
}

int main() {
    int n, k;
    cin >> n >> k;
    vector<pair<int, int>> customers;
    priority_queue<int, vector<int>, greater<int>> windows; // greater<int> 变成 小顶堆,去掉则是默认的大顶堆

    for (int i = 0; i < k; i++) {
        windows.push(8 * 3600); // 银行开门时间为08:00:00
    }

    for (int i = 0; i < n; i++) {
        char time[9];
        int p;
        scanf("%s %d", time, &p);
        int hh = (time[0] - '0') * 10 + (time[1] - '0');
        int mm = (time[3] - '0') * 10 + (time[4] - '0');
        int ss = (time[6] - '0') * 10 + (time[7] - '0');
        int arriveTime = time2int(hh, mm, ss);
        if (arriveTime > 17 * 3600) continue; // 超过17:00:00的顾客不服务
        customers.push_back({arriveTime, p * 60});
    }

    sort(customers.begin(), customers.end());

    double totalWaitTime = 0;
    for (auto &customer : customers) {
        int arriveTime = customer.first;
        int processTime = customer.second;
        int earliestWindow = windows.top();
        windows.pop();

        int startTime = max(arriveTime, earliestWindow);
        int waitTime = startTime - arriveTime;
        totalWaitTime += waitTime;

        windows.push(startTime + processTime);
    }

    if (customers.empty()) {
        printf("0.0\n");
    } else {
        printf("%.1f\n", totalWaitTime / 60.0 / customers.size());
    }

    return 0;
}
---

一些心得

1、要找一组数中最大或最小的数,可以用priority_queue这种结构,其底层是用实现的

2、要比较时间的大小,考虑将HH:MM:SS的格式换成统一的作为单位,可以直接相加减而不用考虑“满60进一”的问题

时间 08:30:00 转换为秒数为 8 * 3600 + 30 * 60 + 0 = 30600 秒

时间 09:15:30 转换为秒数为 9 * 3600 + 15 * 60 + 30 = 33330 秒

计算时间差值:33330 - 30600 = 2730 秒


拓展

priority_queue的使用

1、默认是大顶堆

#include <iostream>
#include <queue>
using namespace std;

int main() {
    priority_queue<int> pq;  // 默认是大顶堆
    pq.push(5);
    pq.push(1);
    pq.push(8);
    pq.push(3);

    while (!pq.empty()) {
        cout << pq.top() << " ";  // 输出最大值
        pq.pop();
    }
    return 0;
}

输出:8 5 3 1


2、小顶堆

#include <iostream>
#include <queue>
using namespace std;

int main() {
    priority_queue<int, vector<int>, greater<int>> pq;  // 小顶堆
    pq.push(5);
    pq.push(1);
    pq.push(8);
    pq.push(3);

    while (!pq.empty()) {
        cout << pq.top() << " ";  // 输出最小值
        pq.pop();
    }
    return 0;
}

输出:1 3 5 8


3、结构体优先队列

#include <iostream>
#include <queue>
using namespace std;

struct Node {
    int x, y;
    bool operator<(const Node &other) const {  // 小的优先
        return x > other.x;
    }
};

int main() {
    priority_queue<Node> pq;
    pq.push({3, 100});
    pq.push({1, 200});
    pq.push({5, 50});

    while (!pq.empty()) {
        cout << pq.top().x << " " << pq.top().y << endl;
        pq.pop();
    }
    return 0;
}

输出:

1 200
3 100
5 50

4、pair的小顶堆

#include <iostream>
#include <queue>
using namespace std;

int main() {
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    pq.push({3, 100});
    pq.push({1, 200});
    pq.push({5, 50});

    while (!pq.empty()) {
        cout << pq.top().first << " " << pq.top().second << endl;
        pq.pop();
    }
    return 0;
}

输出:

1 200
3 100
5 50