1017. Queueing at Bank (25)-PAT甲级真题(感觉是比较简单的思路了)

1017 Queueing at Bank (25 分)

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(≤10​4​​) - 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 SSare 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 10

Sample Output:

8.2

这个题,用笔自己在纸上面模拟一下过程,第一次模拟肯定容易出错并且费劲,多试试,找到模拟的几个关键数

大概就是上面的过程,关键点

1:结构体排个序列,按照到达时间

2:窗口需要记录结束本次客户服务的时间,并且在下一个用户开始服务的时候,记录下一个用户的等待时间,这个等待时间需要看情况,

如果客户早到达了,那么就是窗口记录的时间(也就是上个用户结束服务的时间)减去用户到达时间

如果客户晚到达,但是窗口早就结束服务了,等待时间就是0

那么这里可能有个问题,客户晚到达了,有好几个窗口怎么办?其实是随便选择的,因为目前只有这个顾客能服务。

同时为了代码的简洁,我们直接统一窗口的最初服务结束时间是8点整

 

/*
K个窗口,到达时间T 和 处理时间P,求平均等待时间
N 总顾客  K窗口数
没有顾客同时到达
08:00开到17:00
早到的等到8点,包括17:01和之后的不会服务
输出保留一位小数

都转换成S ,没进去一个顾客,窗口记录完成 时间,这个顾客等待时间就是本次完
成时间减去顾客到达时间

*/

#include <iostream>

#include <vector>
#include <algorithm>

using namespace std;

struct node  //客户结构体
{
    int hour;
    int minute;
    int second;
    int arriveTime;//用户的到达时间
    int spendTime;//用户需要的服务时间
};
struct window
{
    int severEndTime;//窗口本次服务的结束时间
};
int cmp(node a,node b)
{

    if(a.hour!=b.hour)
        return a.hour<b.hour;
    else if(a.minute!=b.minute)
        return a.minute<b.minute;
    else
        return a.second<b.second;
}

int main()
{
    int N,K;
    cin>>N>>K;
    vector<node> user;
    for(int i=0; i<N; i++)
    {
        int hour,minute,second,arriveTime,spendTime;
        scanf("%2d:%2d:%2d %d",&hour,&minute,&second,&spendTime);
        arriveTime=hour*3600+minute*60+second;//都换成秒
        node a= {hour,minute,second,arriveTime,spendTime*60};
        user.push_back(a);
    }
    sort(user.begin(),user.end(),cmp);//按照到达时间排序


    vector<window> windows;//窗口数组
    for(int i=0; i<K; i++)
    {
        window a= {8*3600};//都换成秒
        windows.push_back(a);
    }
    int pos=0;//记录下一个进去的顾客
    vector<int> wait;//顾客等待时间的队列
    while(pos!=N)//这里pos按照到达时间,顺序指定顾客来服务,因为没同时到达的
    {
        if(user[pos].hour>17)
            break;
        else if(user[pos].hour==17&&(user[pos].minute!=0||user[pos].second!=0))
            break;
        //上面代码是指 超过17点了就算球了,服务不了了
        int minWindow=0;//最近结束服务的窗口编号
        int minTime=windows[minWindow].severEndTime;//最近结束服务的窗口的结束时间

        for(int i=1; i<K; i++)
        {
            //这里需要说明下,因为所有窗口结束时间都是8点,
            //所以直接比大小就行了,时间越小的越早结束,越早服务顾客
                if(windows[i].severEndTime<minTime)
                {
                    minTime=windows[i].severEndTime;
                    minWindow=i;
                }
        }

        //最近结束的窗口是minWindow;
        if(user[pos].arriveTime<=minTime)//客户比窗口结束服务来得早
        {
            int waitTime=minTime-user[pos].arriveTime;
            wait.push_back(waitTime);
           // cout<<windows[minWindow].severEndTime+user[pos].spendTime<<'='<<windows[minWindow].severEndTime;
           // cout<<'+'<<user[pos].spendTime<<endl;
            windows[minWindow].severEndTime=windows[minWindow].severEndTime+user[pos].spendTime;

            pos++;
        }
        else//客户比窗口结束服务来得晚,窗口下一次的服务时间就是本次客户的到达时间加上需要服务的时间
        {
            int waitTime=0;
            wait.push_back(waitTime);
           // cout<<user[pos].arriveTime+user[pos].spendTime<<'='<<user[pos].arriveTime;
           // cout<<'+'<<user[pos].spendTime<<endl;

            windows[minWindow].severEndTime=user[pos].arriveTime+user[pos].spendTime;

            pos++;
        }


    }
    float sum=0;
    for(int i=0; i<wait.size(); i++)
    {
        sum+=wait[i];
    }
    printf("%.1f",sum/60/wait.size());
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值