1017 Queueing at Bank

在这里插入图片描述
在这里插入图片描述

题目大意

有n个客户,k个窗口。已知每个客户的到达时间和需要的时长,如果有窗口就依次过去,如果没有窗口就在黄线外等候(黄线外只有一个队伍,先来先服务),求客户的平均等待时长。银行开放时间为8点到17点,再8点之前不开门,8点之前来的人都要等待,在17点后来的人不被服务。题目还有一个坑点It is assumed that no window can be occupied by a single customer for more than 1 hour.这句话没被用上,如果超过一小时的客户拒绝服务,则第四个测试点会过不去,那意思应该是到了60分钟就让这个人重新排队,那问题来了是重新排在第一个位置还是排在最后一个位置呢?根据测试点给出的数据是排在第一个位置。这就很郁闷了,让他重排还有什么意义吗?所以对于这种超过60分钟的人应该怎么处理?题目直接没处理!既然如此直接不限时不就好了吗,加这一句不是存心误导考生吗?我认为这是这道题的不严谨和疏漏之处。

思路解析

客户结构体node,里面有come为到达时间和process为需要服务的时长。先将所有满足条件的(到来时间点在17点之前的)客户放入数组中,数组的长度就是需要服务的客户的个数。windows数组表示某个窗口的结束时间,一开始所有窗口的值都为8点整。每一个客户到来的时候,选择最早结束时间的窗口,如果最早结束时间比他还早,那么他一来就能被服务,更新window的值;如果最早结束时间比他晚,他需要等待,累加等待的时间,然后更新window的值。 对所有客户要先进行排序,按来的时间的早晚排序,之后再先来先服务。因为涉及分钟和秒数,可以把所有时间暂时先化解成秒数的形式,便于计算。

示例代码

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
class Node {
public:
	int come;//秒
	double process;//秒
};
bool cmp(Node n1, Node n2) {
	return n1.come < n2.come;
}
int main() {
	int n, k;
	scanf("%d %d", &n, &k);
	double sum = 0.0;
	vector<Node> custom;//存放所有符合条件的顾客
	vector<double> windows(k, 28800);//元素为当前时间
	for (int i = 0; i < n; i++) {
		int a, b, c;
		double d;
		scanf("%d:%d:%d %lf", &a, &b, &c, &d);
		int cometime = a * 3600 + b * 60 + c;
		if (cometime > 17 * 3600) continue;
		Node n;
		n.come = a * 3600 + b * 60 + c;
		n.process = d * 60;
		custom.push_back(n);
	}
	sort(custom.begin(), custom.end(), cmp);
	for (int i = 0; i < custom.size(); i++) {
		sort(windows.begin(), windows.end());		
		if ((windows[0] - custom[i].come) > 0) {//来早了就得等
			sum += (windows[0] - custom[i].come);
			windows[0] += custom[i].process;
		}
		else {
			windows[0] = custom[i].come + custom[i].process;
		}
	}
	printf("%.1f\n", sum / custom.size() / 60);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值