原题传送门 >>>
几个注意点:
1、凡是在17:00:00之前(包括17:00:00)到的顾客,银行都必须把它们完全服务完成。(也就是说,在这之前银行不下班)。
这个设定也太迷惑了吧???
2、17:00:01之后到的顾客,不计入总人数,也没有排队时间。
参考代码:
#include<cstdio>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int END_TIME = 17*3600;
typedef pair<int,int> P;
map<int,int> line;//抵达时间、所需时间
int N,K;
int windows[102];//i号窗口顾客需要的时间,单位是秒
int glTime = 0;//最多17*60*60, 单位为秒
int wholeTime = 0;
int countCustomer = 0;
int init(){
memset(windows,0,102*sizeof(int));
scanf("%d%d",&N,&K);
for(int i = 0; i < N; ++i){
int h, m, s;
scanf("%d:%d:%d",&h,&m,&s);
int t;
scanf("%d",&t);
P tmp;
tmp.first = h*3600 + m * 60 + s;
if(tmp.first <= END_TIME) {++countCustomer;
tmp.second = t*60;
line.insert(tmp);
}
}
if(N < 1){
printf("0.0\n");
}
glTime = 8 * 3600;
return 0;
}
int forward(){
int minTime = INF;
for(int i = 0; i < K; ++i){
if(windows[i] < minTime){
minTime = windows[i];
}
}//找到窗口的最小时间minTime
glTime += minTime;
if(minTime > 0)
{
for(int i = 0; i < K; ++i){
windows[i] -= minTime;
}//所有窗口 减去minTime
}
if(glTime < line.begin()->first){//现在队头是空的,需要等待顾客到来
int waitForCustom = line.begin()->first - glTime;//等待顾客的时间
glTime = line.begin()->first;
for(int i = 0; i < K; ++i){
windows[i]-= waitForCustom;
if(windows[i] < 0) windows[i] = 0;
}
}
for(int i = 0; i < K; ++i){
if(windows[i]==0){//空闲窗口,把队头元素塞进去
if(glTime < line.begin()->first) break;
wholeTime += (glTime - line.begin()->first);
windows[i] = line.begin()->second;
line.erase(line.begin());
if(line.size() == 0){
return -1;
}
}
}
return 0;
}
int solve(){
init();
while(forward()==0);
printf("%.1lf\n",(double)wholeTime/countCustomer/60);
return 0;
}
int main(){
solve();
return 0;
}