pat1017Queueing at Bank (25)

本文讨论了如何在给定的人数和窗口数量下,优化银行服务排队的算法,通过合理分配服务窗口和顾客等待时间,计算出平均等待时间,并解决了排队问题的复杂性。文中详细解释了算法步骤,包括将所有时刻转换为秒,排序顾客到达和需求时间,以及更新窗口空闲时刻等关键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意分析:

(1)给出N个人的到达银行的时间和需要被服务的时间,在K个窗口的情况下,求出所有人的平均等待时间,对于5点以后到达的人不计算在内。

(2)看似是排队的问题,需要先固定每个人在哪个窗口队列的哪个位置以及他前面的人的服务时间,同时也依赖于他的到达时间和当前第一个人被服务了多长时间,这样看来问题变得复杂了许多,我们将问题简化成这样:每个窗口只维护自己的空闲时刻(8:00开始),谁最先空闲了,就选择等待队列中最早到达银行的开始服务,这样这个人的等待时间就等于此窗口的空闲时刻-客户到达时刻,注意:若此值为正,说明这个窗口在服务上一个人期间,这个人就到达了,他需要等待,若小于等于0,说明此人在这个窗口空闲时刻之前都还没有到达银行,那么可想而知,一旦他到达银行,他不需要等待,直接获取服务,服务结束后,更新此窗口的空闲时刻。依次类推,直到队列为空或者只剩下17:00以后到达的人。

(3)为了计算的方便,我们将所有的时刻全部算成秒,如:8:00就是8*3600秒

(4)每次都要计算最先空闲的窗口,因此必然涉及到排序。

(5)在服务结束后,更新窗口的空闲时刻需要注意:若客户到达的时候,窗口不空闲,那么意味着这个窗口服务完上一个人后立即服务这个人,因此这个窗口的下一次空闲时刻是本次空闲时刻+此人的服务时间,反之,若在空闲时刻时候到达的,那么窗口一直要等到他到达银行,再给他服务,因此下一次的空闲时刻=此人到达时间+服务时间

可能坑点:

(1)不要忽略等待人数为0的情况;

(2)统计的时候需要过滤掉在17:00之后到达的人

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;

int window[101];
struct cus
{
    int arrayTime;
    int serveTime;
};
cus Cus[10001];
bool cmp2(int a,int b)
{
    return a<b;
}
bool cmp1(cus a,cus b)
{
    return a.arrayTime<b.arrayTime;
}
int main()
{
    int N,K;
    cin>>N>>K;
    int hh,mm,ss,wait;
    for(int k=0;k<K;k++)window[k]=3600*8;
    int a=0,i=0;
    while(a<N)
    {
        scanf("%d:%d:%d %d",&hh,&mm,&ss,&wait);
        if(hh*3600+mm*60+ss<17*3600+1)
        {
            Cus[i].arrayTime=hh*3600+mm*60+ss;
            Cus[i].serveTime=wait*60;
            i++;
        }
        a++;
    }
    sort(&Cus[0],&Cus[i],cmp1);
    int count=0;
    double total=0;
    for(int j=0;j<i;j++)
    {
        sort(&window[0],&window[K],cmp2);
        if(window[0]>Cus[j].arrayTime)
        {
            total+=(window[0]-Cus[j].arrayTime);
            window[0]+=Cus[j].serveTime;
        }
        else
        {
            window[0]=Cus[j].serveTime+Cus[j].arrayTime;
        }
        count++;
    }
    if(count>0)printf("%.1lf\n",(total/60)/count);
    else cout<<"0.0"<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值