题目连接
题目大意
给定N个顾客,K个服务窗口一系列的用户到达时间,需要服务的时间。最后需要输出平均等待时间。注意,只考虑在银行营业期间到来的顾客。
思路
- 由于给的时间数据(
hh:mm:ss
)有点麻烦,为了方便计算需要先转化为最小的时间粒度单位,比如秒。时间统一转化函数如下:int convertTime(int h, int m, int s) { return h * 3600 + m * 60 + s; }
- 设置一个数组W[105],表示的是窗口结束服务时间,初始为08:00(需要转化为秒)。对到来的每一个顾客,分两种情况,更新窗口的结束服务时间。每个顾客遍历K个窗口,时间复杂度为O(WN)
AC代码
#include<iostream>
#include<algorithm>
#include<vector>
#define INF ((1 << 31) - 1)
using namespace std;
struct customer {
int comeTime, serveTime;
}newCustomer;
//保存K个窗口的结束使用时间
int w[105];
vector<customer> que;
int convertTime(int h, int m, int s) {
return h * 3600 + m * 60 + s;
}
bool cmp(customer a, customer b) {
return a.comeTime < b.comeTime;
}
int main() {
int c, wNums, totalTime = 0;
int openTime = convertTime(8, 0, 0);
int closeTime = convertTime(17, 0, 0);
scanf("%d%d", &c, &wNums);
for (int i = 0; i < wNums; i++) w[i] = openTime;
for (int i = 0; i < c; i++) {
int h, m, s,serveTime;
scanf("%d:%d:%d %d", &h, &m, &s, &serveTime);
int comeTime = convertTime(h, m, s);
if (comeTime < closeTime) {
newCustomer.comeTime = comeTime;
newCustomer.serveTime = serveTime > 60 ? 3600 : serveTime * 60;
que.push_back(newCustomer);
}
}
sort(que.begin(), que.end(), cmp);
for (int i = 0; i < que.size(); i++) {
int idx = -1, minEndTime = INF;
//最早可用窗口
for (int j = 0; j < wNums; j++) {
if (w[j] < minEndTime) {
minEndTime = w[j];
idx = j;
}
}
if (que[i].comeTime < w[idx]) { //需要等,计算此customer等待时间
totalTime += w[idx] - que[i].comeTime;
w[idx] += que[i].serveTime;
}
else {
w[idx] = que[i].comeTime + que[i].serveTime;
}
}
printf("%.1f", totalTime*1.0 / (que.size() * 60));
return 0;
}