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 (<=10000) - 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 10Sample Output:
8.2
案例分析:
7个顾客,3个队伍
对顾客的时间排序,
顾客 | 服务时间 | 开始时间 | 等待时间 |
---|---|---|---|
07:55:00 | 16 | 08:00:00 | 00:05:00 |
07:59:59 | 15 | 08:00:00 | 00:00:01 |
08:00:00 | 30 | 08:00:00 | 00:00:00 |
08:00:02 | 2 | 08:15:00 | 00:14:58 |
08:01:00 | 60 | 08:16:00 | 00:15:00 |
08:03:00 | 10 | 08:17:00 | 00:14:00 |
17:00:01 | 2 | Sorry | 无 |
总等待时间为00:48:59,6个人,平均等待时间为8.2分钟
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
struct Time{
int hour;
int minute;
int second;
};//时间结构体
int turn2sec(Time T){
return T.hour * 60 * 60 + T.minute * 60 + T.second;
}//把时间化为秒
struct Customer{
int s_time;
int server_time;
bool operator < (const Customer &A)const{
return s_time < A.s_time;
}//顾客结构体,以及比较函数,按到达的先后
}buf[10002];
int ans[10002];//存储各个顾客的等待时间
int queue[102];//队伍,存储顾客编号
int main(void){
//freopen("F://Temp/input.txt", "r", stdin);
int N, K;
while (scanf("%d%d", &N, &K) != EOF){
Time tmp;
for(int i = 0; i < N; i ++){
scanf("%d:%d:%d", &tmp.hour, &tmp.minute, &tmp.second);
buf[i].s_time = turn2sec(tmp);
int server;
scanf("%d", &server);
buf[i].server_time = server * 60;
}
sort(buf, buf + N);
for (int i = 0; i < K; i++){
queue[i] = -1;
}
for (int i = 0; i < N; i++){
ans[i] = -1;
}//初始化
int count = 0;
for (int t = 28800; t <= 864000 && buf[count].s_time <= 61200; t++){//为了应对五点前有顾客开始服务,但是结束的时间超过五点,所以这里的t设置的很大
for (int i = 0; i < K; i++){
if (queue[i] != -1){
int tmp = queue[i];
if ((buf[tmp].s_time + ans[tmp] + buf[tmp].server_time) == t){//如果到达时间+等待时间(即开始时间)+服务时间==当前时间,则出对
queue[i] = -1;
}
}
}
for (int i = 0; i < K; i++){
if (queue[i] == -1 && t >= buf[count].s_time){
queue[i] = count;//如果队伍有空,并且当前时间大于顾客的到达时间,则入队
ans[count] = t - buf[count].s_time;//并计算等待时间
count++;
}
}
}
int sum = 0;
int i;
for (i = 0; i < N; i++){
if (ans[i] == -1)break;
else{
sum += ans[i];
}
}
if (i == 0)printf("0/n");
else printf("%.1f\n", (double)sum / i / 60);
}
return 0;
}
我的思路比较传统
顾客 | 服务时间 | 开始时间 | 等待时间 |
---|---|---|---|
07:55:00 ① | 16 | 08:00:00 | 00:05:00 |
07:59:59 ② | 15 | 08:00:00 | 00:00:01 |
08:00:00 ③ | 30 | 08:00:00 | 00:00:00 |
08:00:02 ④ | 2 | 08:15:00 | 00:14:58 |
08:01:00 ⑤ | 60 | 08:16:00 | 00:15:00 |
08:03:00 ⑥ | 10 | 08:17:00 | 00:14:00 |
17:00:01 | 2 | Sorry | 无 |
就拿这个例子来说,窗口初始值都为08:00:00,①②③号顾客分别在(1),(2),(3)窗口他们办理业务时窗口值更新为08:16:00 08:15:00
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
string opentime="08:00:00",closetime="17:00:00";
struct customer
{
string comtime;
int servetime;
}c[10001];
vector<string> windows(101,opentime);//窗口
string cal1(string ctmp,int wtmp)//计算开始服务时间+服务时间,例如开始服务时间为08:00:00,服务时间为16min,计算结果返回08:16:00
{
int ctmin,ltmin,cthour,lthour,flag=0;
string ltmp=ctmp;
ctmin=stoi(ctmp.substr(3,2));
cthour=stoi(ctmp.substr(0,2));
ltmin=wtmp+ctmin;
if(ltmin>60)
{
ltmin-=60;
flag=1;
}
lthour=cthour+flag;
ltmin>=10?ltmp.replace(3,2,to_string(ltmin)):ltmp.replace(3,2,'0'+to_string(ltmin));
lthour>=10?ltmp.replace(0,2,to_string(lthour)):ltmp.replace(0,2,'0'+to_string(lthour));
return ltmp;
}
int cal2(string t1,string t2)//计算两个时间点的时间差,以秒为单位,例如输入08:00:00与08:01:00,输出就是60秒
{
int th1=stoi(t1.substr(0,2)),tm1=stoi(t1.substr(3,2)),ts1=stoi(t1.substr(6,2));
int th2=stoi(t2.substr(0,2)),tm2=stoi(t2.substr(3,2)),ts2=stoi(t2.substr(6,2));
if(ts2<ts1)
{
tm2-=1;
ts2+=60;
}
if(tm2<tm1)
{
th2-=1;
tm2+=60;
}
return (th2-th1)*3600+(tm2-tm1)*60+(ts2-ts1);
}
int cmp(customer a,customer b)//sort里用的compare函数
{
return a.comtime<b.comtime?1:0;
}
int findmin(int k)//找到所有k个窗口中结束时间最早的
{
int mini=0;
string min="99:59:59";
for(int i=0;i<k;i++)
if(min>windows[i])
{
mini=i;
min=windows[i];
}
return mini;
}
int main(){
int n,k,wtmp,no=0,time=0,notmp=0;
double avg;
string ctmp;
cin>>n>>k;
for(int i=0;i<n;i++)
{
cin>>ctmp>>wtmp;
if(ctmp<=closetime)
{
c[no].comtime=ctmp;
c[no++].servetime=wtmp;
}
}
sort(c,c+no,cmp);//排序
for(int i=0;i<n&&c[i].comtime<opentime;i++)//先计算08:00:00前到的,这些人都要等
{
time+=cal2(c[i].comtime,opentime);
c[i].comtime=opentime;
}
while(notmp<no)//对每个顾客分别计算等待时间,注意这个顾客前面有空窗口和没有时,time的值和windows的值要分别计算
{
int fmin=findmin(k);
int timetmp=cal2(c[notmp].comtime,windows[fmin]);
time+=(timetmp>0?timetmp:0);
windows[fmin]=cal1(max(windows[fmin],c[notmp].comtime),c[notmp].servetime);
notmp++;
}
avg=(time*1.0)/(60*no);
printf("%.1lf\n",avg);
return 0;
}