题目大意:银行有K个窗口,给出N个人的到达时间和办理业务需要的时间,银行从8:00开始营业,求出每个在17:00前到达的人的平均等待时间。每个人的业务时间不能超过1h(事实上没有测试点对应这句话)。
一开始是想把时间全部折算成从8:00开始计算的分钟的,但是这样到最后double和int很容易弄混,弄混了精度就丢失了,导致测试点5始终过不了,所以还是全部折算成从8:00开始计算的秒比较合适。
然后就是所有人按到达时间排序,依次处理。首先找到最小空出时间的窗口,如果当前处理的人的到达时间小于最小空出时间,那么总的等待时间需要更新,最小空出时间窗口的信息需要更新为 freeAtTime += processTime;如果当前处理的人的到达时间大于等于最小空出时间,那么不需要等待,最小空出时间的窗口的信息更新为 freeAtTime = arriveTime + processTime。
AC代码如下:
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
int timeToSec(int hour, int min, int sec)
{
return hour * 3600 + min * 60 + sec - 8 * 3600;
}
struct customer
{
int arriveTime;
int processTime;
bool operator <(const customer& other)
{
return this->arriveTime < other.arriveTime;
}
};
const int MAXK = 110;
int freeAtTime[MAXK] = {0}; //从8:00开始计时
int main()
{
int N, K;
scanf("%d%d", &N, &K);
vector<customer> v(N);
for (int i = 0; i < N; ++i)
{
int hour, min, sec, processTime;
scanf("%d:%d:%d %d", &hour, &min, &sec, &processTime);
if(hour < 17 || (hour == 17 && min == 0 && sec == 0))
{
v[i].arriveTime = timeToSec(hour, min, sec);
v[i].processTime = processTime <= 60? processTime * 60 : 60 * 60;
}
else
{
i--;
N--;
}
}
sort(v.begin(), v.begin() + N);
double totalWaitTime = 0;
for (int i = 0; i < N; ++i)
{
int minIndex = 0, minFreeTime = 0x7FFFFFFF;
for (int j = 0; j < K; ++j)
{
if(freeAtTime[j] < minFreeTime)
{
minFreeTime = freeAtTime[j];
minIndex = j;
}
}
if(v[i].arriveTime < minFreeTime)
{
totalWaitTime += minFreeTime - v[i].arriveTime;
freeAtTime[minIndex] += v[i].processTime;
}
else
freeAtTime[minIndex] = v[i].arriveTime + v[i].processTime;
}
printf("%.1f", totalWaitTime / 60.0 / N);
return 0;
}