PAT 甲级测试题目 -- 1017 Queueing at Bank
题目概要
银行有 N 个顾客和 K 个窗口。来办理业务的顾客必须等待在黄线之后,直到 8:00 开始办理业务。给出顾客到达银行的时间 HH:MM:SS(HH 的范围是[00, 23], MM 和 SS 的范围均为 [00, 59]),以及办理业务需要的时间 P(单位是分钟)。17:00 之后到店的顾客不予以服务。
分析
有了 1016 题柳神对于时间处理的经验,使得我能更好的处理这道题的细节问题。但是要注意下述几个问题:
- 顾客数量为 0 时,由于计算平均时间需要 顾客数量 为分母,因此顾客数量为 0 直接输出 0.0就好了。
- 黄线是否能容纳下所有光临的顾客
注意了上述问题之后,我的思路是: - 初始化窗口办理完成的时间为 8:00。到店时间小于这个值的顾客,其差值为该顾客的等待时间,大于则直接办理,没有等待时间,当窗口办理完成的时间更新之后思路也是一样的。
- 之后在迭代的过程中,找出“初始化窗口办理完成的时间”的最小值,将后续的顾客加入进去,同时计算等待时间
实现
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
int hour, minutes, second, processTime, time;
};
bool cmp1(node a, node b) {
return a.time < b.time;
}
bool cmp2(int a, int b) {
return a < b;
}
int main() {
int N, K; // 顾客数量 窗口数量
cin >> N >> K;
// 处理顾客为 0 的情况
if (N == 0) {
printf("%.1f", 0.0);
return 0;
}
// 初始化 各个窗口的营业时间为 8:00
int windows[100];
for (int i = 0; i < K; ++i) {
windows[i] = 8 * 60 * 60;
}
vector<node> customers;
int giveup = 0;
for (int i = 0; i < N; ++i) {
node temp;
scanf("%02d:%02d:%02d %d", &temp.hour, &temp.minutes, &temp.second, &temp.processTime);
temp.time = temp.hour * 60 * 60 + temp.minutes * 60 + temp.second;
// 处理 17:00 之后进来的顾客
if (temp.time >= 17 * 3600) {
giveup++;
}
customers.push_back(temp);
}
// 丢弃这些顾客
N -= giveup;
sort(customers.begin(), customers.end(), cmp1);
double total = 0; // 总共的等待时间
// 处理顾客
for (int i = 0; i < N; ++i) {
vector<node>::iterator iter = customers.begin();
sort(windows, windows + K, cmp2);
if (windows[0] > iter->time) {
total += windows[0] - iter->time;
windows[0] += iter->processTime * 60;
customers.erase(iter);
} else {
windows[0] = iter->time + iter->processTime * 60;
customers.erase(iter);
}
}
// 输出答案
printf("%.1f", total / (double) N / 60.0);
return 0;
}
一次就 AC 了还是比较开心的
希望能帮到大家!