Suppose a bank has K windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. All the customers have to wait in line behind the yellow line, until it is his/her turn to be served and there is a window available. It is assumed that no window can be occupied by a single customer for more than 1 hour.
Now given the arriving time T and the processing time P of each customer, you are supposed to tell the average waiting time of all the customers.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 numbers: N (≤10^4 ) - the total number of customers, and K (≤100) - the number of windows. Then N lines follow, each contains 2 times: HH:MM:SS - the arriving time, and P - the processing time in minutes of a customer. Here HH is in the range [00, 23], MM and SS are both in [00, 59]. It is assumed that no two customers arrives at the same time.
Notice that the bank opens from 08:00 to 17:00. Anyone arrives early will have to wait in line till 08:00, and anyone comes too late (at or after 17:00:01) will not be served nor counted into the average.
Output Specification:
For each test case, print in one line the average waiting time of all the customers, in minutes and accurate up to 1 decimal place.
Sample Input:
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
Sample Output:
8.2
题目大意:
输入N个用户,每个用户有一个到达时间和服务时间,总共有M个服务窗口,到达时间在8:00-17:00中的顾客能被服务,问顾客的平均等待时间是多少?
解题步骤:
- 读入数据,将时间转换为以秒为单位计算,读入时确定该用户是否能被服务,即达到时间是否超过17:00
- 将到达的用户按到达时间排序
- 为每个窗口设定一个变量记录当前窗口的上一个顾客服务结束的时间,称为基准时间,因为所有窗口是8点开始服务,所有8点前到达的用户需等待,所以一开始将所有基准时间设置为8点,可理解为8点前每个窗口前都有一个虚拟的用户在占用服务。
- 每次循环,选出基准时间最小的窗口,为下一个用户进行服务,这里可能出现的有两种情况:一、用户到达时间小于基准时间(前一个用户还没处理完下一个就来了),这就需要得到前一个完再进行服务,二、用户到达时间大于或等于基准时间(前一个结束后下一个才来),这种就能直接进行服务。根据以上两种情况对用户等待时间和基准时间进行更新。
解题收获:
- 对时间的处理尽量转换为整数
- 对银行窗口的模拟最好对每个窗口设置一个时间,而不是设置一个全局的时间
- 结果包含除数时应考虑分母是否可能为0
代码:
#include <bits/stdc++.h>
using namespace std;
typedef struct customer{
int arrive_time; // 到达时间
int process_time; // 处理时间
int wait_time; // 等待时间
int canbe_serve; // 是否能被处理
}cus;
const int inf = 9999999;
int N; // (≤10^4 the total number of customers
int K; // (≤100) the number of window
bool static cmp(cus& a, cus&b){
return a.arrive_time < b.arrive_time;
}
int main(int argc, char const *argv[])
{
cin >> N >> K;
int hh, mm, ss, t;
vector<cus> customers(N);
int cnt = 0; // 处理的顾客的个数
for(int i = 0;i < N; i++){
scanf("%d:%d:%d %d", &hh, &mm, &ss, &t);
if(hh*3600+mm*60+ss <= 17*3600){
customers[i].arrive_time = hh*3600+mm*60+ss;
customers[i].process_time = t*60;
customers[i].canbe_serve = 1;
}
else
customers[i].canbe_serve = 0;
}
// 按到达时间排序
sort(customers.begin(), customers.end(), cmp);
vector<int> baseTime(K, 8*3600); // 直接把每个窗口的基准时间设置为开始服务的时间
int p = 0;
while(p < N){
// 看哪个窗口当前服务结束时间最早
int index = -1, minBaseTime = inf;
for(int i = 0;i < K; i++){
if(baseTime[i] < minBaseTime){
minBaseTime = baseTime[i];
index = i;
}
}
if(customers[p].canbe_serve == 1){
if(customers[p].arrive_time < baseTime[index]){
customers[p].wait_time = baseTime[index] - customers[p].arrive_time;
baseTime[index] += customers[p].process_time;
}
else if(customers[p].arrive_time >= baseTime[index]){
customers[p].wait_time = 0;
baseTime[index] = customers[p].arrive_time + customers[p].process_time;
}
}
p++;
}
double ans = 0.0;
for(int i = 0;i < N; i++){
if(customers[i].canbe_serve == 1){
ans += customers[i].wait_time;
cnt++;
}
}
if(cnt == 0)
cout << "0.0" << endl;
else
printf("%.1lf\n",ans / cnt / 60 );
return 0;
}
395

被折叠的 条评论
为什么被折叠?



