我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED
原题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805491530579968
题目描述:
题目翻译:
1017 银行排队
假设银行有K个窗口开放供服务。窗户前面有一条黄线,将等候区分成两部分。所有客户都必须排在黄线后排队,直到他/她轮到他并且有一个可用的窗口。假设单个客户不能占用任何窗口超过1小时。
现在给出每个客户的到达时间T和处理时间P,你需要告诉算出客户的平均等待时间。
输入格式:
每个输入文件包含一个测试用例。对每个测试用例,第一行包含2个数字:N(<= 10 ^ 4)——客户总数,K(<= 100)——窗口数。然后是N行,每行包含2个时间:HH:MM:SS——到达时间,P——客户的处理时间(以分钟为单位)。这里HH在[00,23]范围内,MM和SS都在[00,59]中。假设没有两个客户同时到达。
请注意,银行的开放时间为08:00至17:00。任何提前到达的人都必须排队等到08:00,任何人来得太晚(在17:00:01或之后)都不会被送达或计入平均值。
输出格式:
对每个测试用例,在一行中打印所有客户的平均等待时间,以分钟为单位,精确到小数点后1位。
输入样例:
7 3
07:55:00 16
17:00:01 2
07:59:59 15
08:01:00 60
08:00:00 30
08:00:02 2
08:03:00 10
输出样例:
8.2
知识点:排序
思路:用一个数组window记录每个窗口所能提供下一次服务的最早时间
首先把时间都转换成秒来表示,对客户按到达时间排序,只考虑在15点之前到达的客户。
window数组的的初始化值应该是8点,转换成秒就是8 * 60 * 60。
对于每个客户,计算当前window数组中的最小值,即最早能接待该客户的窗口。
如果客户的到达时间迟于该窗口能接待用户的最早时间,那么该客户无需等待,更新该窗口能接待下一个客户的最早时间。
如果客户的到达时间早于该窗口能接待用户的最早时间,那么该用户需要等待,更新该窗口能接待下一个客户的最早时间。
时间复杂度是O(NlogN)。空间复杂度是O(N)。
C++代码:
#include<iostream>
#include<algorithm>
using namespace std;
struct person {
int arrive;
int process;
person() {}
person(int _arrive, int _process) : arrive(_arrive), process(_process) {};
};
int earliest = 8 * 60 * 60;
int latest = 15 * 60 * 60;
int changeToSecond(int hour, int minute, int second);
bool cmp(person p1, person p2);
int main() {
int N, K;
scanf("%d %d", &N, &K);
person people[N];
int window[K]; //每个窗口能接受下一次服务的最早时间
fill(window, window + K, earliest);
int hour, minute, second, process;
for(int i = 0; i < N; i++) {
scanf("%d:%d:%d %d", &hour, &minute, &second, &process);
people[i] = person(changeToSecond(hour, minute, second), process * 60);
}
sort(people, people + N, cmp);
int wait = 0;
int count = 0;
for(int i = 0; i < N; i++) {
if(people[i].arrive > latest) {
continue;
}
count++;
int earlistWindow = 0;
for(int j = 1; j < K; j++) {
if(window[j] < window[earlistWindow]) {
earlistWindow = j;
}
}
if(window[earlistWindow] > people[i].arrive) { //如果客户来的时候需要等待
wait += window[earlistWindow] - people[i].arrive;
window[earlistWindow] += people[i].process;
}else{ //如果客户来的时候不需要等待
window[earlistWindow] = people[i].arrive + people[i].process;
}
}
printf("%.1f\n", wait * 1.0 / (60 * count));
return 0;
}
int changeToSecond(int hour, int minute, int second) {
return hour * 60 * 60 + minute * 60 + second;
}
bool cmp(person p1, person p2) {
return p1.arrive < p2.arrive;
}
C++解题报告: