题目描述
链接
有n个客户,k个窗口。已知每个客户的到达时间和需要的时长,如果有窗口就依次过去,如果没有窗口就在黄线外等候(黄线外只有一个队伍,先来先服务),求客户的平均等待时长。银行开放时间为8点到17点,再8点之前不开门,8点之前来的人都要等待,在17点后来的人不被服务。
分析
- 仔细模拟题意啊!!!!分情况讨论!!!见代码
- 写代码开数组空间的时候!!一定慎重!!!!!!!!因为这个WA无数次了
代码
#include<bits/stdc++.h>
using namespace std;
int n,k;
const int maxn = 1e4+10;
struct window{
int ed;
}wins[maxn];
struct node{
int enter;
int st;
int cost;
int ed;
}nodes[maxn];
int cal(int h,int m,int s){
return h*3600 + m*60 + s;
}
bool cmp(node x, node y){
return x.enter < y.enter;
}
int hh,mm,ss,cost;
int main(){
scanf("%d%d",&n,&k);
int len = 0;
for(int i=0;i<n;i++){
scanf("%d:%d:%d %d",&hh,&mm,&ss,&cost);
if(hh > 17 || hh == 17 && mm > 0 || hh==17 && mm == 0 && ss > 0){
continue;
}
nodes[len++] = {cal(hh,mm,ss), 0, cost*60, 0};
}
sort(nodes,nodes+len,cmp);
int wait = 0;
for(int i=0;i<len;i++){
int min = 0;
for(int j=0;j<k;j++){ //找出最近的结束使用时间
if(wins[min].ed > wins[j].ed) min = j;
}
if(wins[min].ed <= nodes[i].enter){ //如果进来的时候窗口已经是可用了
if(nodes[i].enter < 8*3600){ //特殊情况是进来时还没开窗口
wait += 8*3600 - nodes[i].enter;
nodes[i].st = 8*3600;
nodes[i].ed = nodes[i].st + nodes[i].cost;
wins[min].ed = nodes[i].ed;
}else{ //立马就用
wait += 0;
nodes[i].st = nodes[i].enter;
nodes[i].ed = nodes[i].st + nodes[i].cost;
wins[min].ed = nodes[i].ed;
}
}else{ //进来时窗口还在忙,必须等待
wait += wins[min].ed - nodes[i].enter;
nodes[i].st = wins[min].ed;
nodes[i].ed = nodes[i].st + nodes[i].cost;
wins[min].ed = nodes[i].ed;
}
}
printf("%.1f
", wait*1.0/60/len);
}