1017 Queueing at Bank 模拟

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 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 10
Sample Output:
8.2

真的是模拟虐我千百遍啊,做的真烦,主要是自己想的做法是很麻烦,不能很简洁的求解出来,写出的代码还得调的比较久;
网上找了一个简洁的做法,真的是又简洁又清晰。
摘抄一下思路:
来自:https://blog.csdn.net/xyt8023y/article/details/46050717
给每个窗口记录一个时间,代表当前服务的顾客结束的时间,每次取出最早结束服务的窗口,如果等待队列中最前面的顾客到达的时间比这个时间早,说明在等待中,一直要等到服务结束,因此等待时间等于这两个时间的差,此时,窗口的服务结束时间应该被更新为原来的时间(即新顾客开始服务的时间)加上新顾客服务的时间;如果等待队列中最前面的顾客到达时间大于窗口结束服务的时间,说明无需等待,直接服务,这时候窗口的结束服务时间应该被更新为新顾客的到达时间加上服务的持续时间。

为了得到队列最前面的顾客和最早结束服务的窗口,创建两个优先队列,分别管理所有顾客和所有窗口。

STL中的优先队列priority_queue是最大堆容器,默认使用<来比较元素,显然本题目中顾客和窗口的存取规律满足最小堆,因此重载<来实现最小堆。

虽然时间包含时、分、秒,为了简便,都以秒的总和来存储,并且取时间基准为8:00:00对应的秒数28800,因为服务最晚到17:00:01之前,因此取时间上限为61201,在初始化时把所有窗口的服务结束时间设定为28800,也就是说在8:00:00之前到达的顾客需要等待到8:00:00才能接受服务。

为了排除不能服务的人加入平均时间计算,应该在遍历顾客队列时设定一个变量cnt,记录能够被服务的人的数量,在顾客到达时间大于等于时间上限时,及时中断循环避免时间浪费。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define pb push_back
#define mp make_pair
#define fi first
#define se second

struct people{
    int h,m,s;
    int con;
    int tol;
    people(int h,int m,int s,int con):h(h),m(m),s(s),con(con){
        tol = h * 3600 + m * 60 + s;
    }
    friend bool operator < (const people &p,const people &q){
        return p.tol > q.tol;
    }
};

struct window{
    int tol;
    window(int tol):tol(tol){}
    friend bool operator < (const window &p,const window &q){
        return p.tol > q.tol;
    }
};

priority_queue<people>peo;
priority_queue<window>win;

int main()
{
    int n,k;
    scanf("%d %d",&n,&k);
    for(int i = 0;i < n;++i){
        int h,m,s,d;
        scanf("%d:%d:%d %d",&h,&m,&s,&d);
        peo.push(people(h,m,s,d * 60));
    }

    int timeMIN = 28800;
    int timeMAX = 61200;
    int ans = 0;
    int cnt = 0;

    for(int i = 0;i < k;++i){
        win.push(window(timeMIN));
    }

    while(!peo.empty()){
        people peotmp = peo.top();
        peo.pop();

        if(peotmp.tol > timeMAX) break;
        cnt++;
        window wintmp = win.top();
        win.pop();
        if(peotmp.tol < wintmp.tol){
            ans += (wintmp.tol - peotmp.tol);
            wintmp.tol += peotmp.con;
        }else{
            wintmp.tol = peotmp.tol + peotmp.con;
        }
        win.push(wintmp);
    }
    printf("%.1f\n",ans / cnt / 60.0);

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值