PAT 1017 Queueing at Bank—优先队列模拟

题解

原题链接
用两个优先队列,一个存储顾客到达时间,另一个存储窗口空闲时间点

#include <iostream>
#include <queue>
#include <cstdio>
#define MIN 8*60*60
#define MAX 17*60*60
#define tosec(a,b,c) a*60*60+b*60+c

using namespace std;

typedef pair<int, int> P;

struct cmp
{
    bool operator()(const P p1, const P p2)
    {
        return p1.first > p2.first;
    }
};

int main()
{
    priority_queue<P, vector<P>, cmp> cust;
    priority_queue<int, vector<int>, greater<int> > window;
    int N, K, hh, mm, ss, servt, len;
    double waitsum=0;
    scanf("%d %d",&N, &K);
    for (int i=0; i<N; i++)
    {
        scanf("%d:%d:%d %d",&hh, &mm, &ss, &servt);
        servt *= 60;
        if (servt > 3600)
            servt = 3600;
        if (tosec(hh,mm,ss)<=MAX)
        {
            P p1(tosec(hh,mm,ss),servt);
            cust.push(p1);
        }
    }
    len = cust.size();
    if (len <= K)
    {
        while(!cust.empty())
        {
            P p1=cust.top();
            cust.pop();
            if (p1.first < MIN)
                waitsum += (MIN-p1.first);
        }
    }
    else
    {
        for (int i=0; i<K; i++)
        {
            P p1=cust.top();
            if (p1.first >= MIN)
                window.push(p1.first+p1.second);
            else
            {
                waitsum += (MIN-p1.first);
                window.push(MIN+p1.second);
                printf("%.1f\n",waitsum/60);
            }
            cust.pop();
        }
        for (int i=K; i<len; i++)
        {
            int current=window.top();
            window.pop();
            P p1=cust.top();
            cust.pop();
            if (p1.first >= current)
                window.push(p1.first+p1.second);
            else
            {
                waitsum += (current-p1.first);
                window.push(current+p1.second);
                printf("%.1f\n",waitsum/60);
            }
        }
    }
    if (waitsum == 0)
        printf("0.0");
    else
    {
        waitsum /= len;
        printf("%.1f",waitsum/60);
    }
    return 0;
}

end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值