【1017 25 时间运算】 Queueing at Bank

传送门

题意

\(n\) 个客户,\(k\) 个窗口。已知每个客户的到达时间和需要的时⻓,如果有窗⼝就依次过去, 如果没有窗⼝就在黄线外等候(黄线外只有一个队伍,先来先服务),银行开放时间为 \(8\) 点到 \(17\) 点,在 \(8\) 点之前不开门,\(8\) 点之前来的人都要等待,在 \(17\) 点后来的人不被服务。求客户的平均等待时长。

数据范围

\(n\leq 10^{4}\)
\(1\leq k\leq 100\)

题解

  • 服务时间是分钟要转化成秒
  • 将时间全部转化成从 \(0\) 开始的秒进行运算
  • 到达超过时间的人不计算,等待超过时间的计算
  • 按照当前人到达时间 arrive 和最小的窗口结束时间 time 分为两种情况
    • arrive < time,更新 time = time + service, res += time - arrive
    • arrive > time,更新 time = arrive + service

Code

#include <bits/stdc++.h>
using namespace std;

#define arrive first
#define service second

int main() {
	int n, k; cin >> n >> k;
	vector<pair<int, int>> customers;
	int start = 8 * 3600, end = 17 * 3600;
	priority_queue<int, vector<int>, greater<int>> windows;
	for (int i = 0; i < k; i++) windows.push(start);
	for (int i = 0; i < n; i++) {
		char c; int h, m, s, service; cin >> h >> c >> m >> c >> s >> service;
		service *= 60;
		int arrive = h * 3600 + m * 60 + s;
		if (arrive < end) customers.push_back({arrive, service});
	}
	double average = 0;
	
	sort(customers.begin(), customers.end());

	for (auto& c : customers) {
		auto it = windows.top(); windows.pop();
		if (it > c.arrive) {
			average += double(it - c.arrive);
			windows.push(it + c.service);
		} else {
			windows.push(c.arrive + c.service);	
		}
	}
	average = average / double(customers.size()) / 60.0;
	cout << fixed << setprecision(1) << average;
}
posted @ 2021-01-31 19:25  Hyx'  阅读(38)  评论(0)    收藏  举报