银行排队问题之单队列多窗口服务 (25 分)

题目如下

 

 注释很详细,全在代码中

#include<bits/stdc++.h>
using namespace std;
class Person//个人信息
{
public:
    int get_time,last_time,wait_time;//到达时间,持续时间,等待时间
    Person(int a,int b):get_time(a),last_time(b),wait_time(0) {}
    Person() {}
};
class Windows//窗口信息
{
public:
    int id,time;//窗口编号和顾客所用该窗口时间
    Windows(int a,int b):id(a),time(b) {}
    Windows() {}
    friend bool operator <(const Windows& a,const Windows& b)
    {
        if(a.time==b.time)
            return a.id>b.id;
        return a.time>b.time;
    }
};
int searchfree(bool* arr,int len)//该函数找出空闲窗口并且id是最小的那个;
{
    for(int i=0; i<len; i++)
    {
        if(arr[i])return i;
    }
    exit(-2);//没找到输入数据有误就退出
    return -1;
}
int main()
{
    int num1,a,b,num2,time;
    cin>>num1;
    vector<Person>v;//储存顾客信息
    for(int i=0; i<num1; i++)
    {
        cin>>a>>b;
        b = b>60 ? 60 : b ;
        v.push_back(Person(a,b));
    }
    cin>>num2;
    int* win_num=new int[num2];//每个窗口接待顾客的数量
    bool* isfree=new bool[num2];//判断该窗口是否空闲
    for(int i=0; i<num2; i++)
    {
        win_num[i]=0;
        isfree[i]=true;
    }
    int id=0,curtime=0,cus_id=0;
    priority_queue<Windows>QW;//储存每个顾客完成服务的时间点
    while(cus_id<num1)//当顾客编号小于今天的顾客数
    {
        if(QW.empty()||v[cus_id].get_time<QW.top().time)//如果窗口都空闲或者该顾客到达的时间点小于所有窗口完成任务的时间点
        {
            if(QW.size()<num2)
            {
                curtime=v[cus_id].get_time;//当前时间来到这个人到达的时间点
                id=searchfree(isfree,num2);//找出空闲窗口的编号
                //
            }
            else
            {
                curtime=QW.top().time;//当前时间来到正在服务的顾客完成服务的时间点
                id=QW.top().id;//编号找出队列中最前面的窗口编号,即为最短时间点且编号最小的窗口编号
                v[cus_id].wait_time=curtime-v[cus_id].get_time;//该顾客的等待时间即为当前时间点减去他来的时间点
                QW.pop();
            }
            time=curtime+v[cus_id].last_time;//时间点即为当前时间加上这个顾客所需的办理业务的时间
            isfree[id]=false;//该窗口不空闲
            QW.push(Windows(id,time));//将窗口编号和窗口完成业务的时间点放进优先级队列
            win_num[id]++;//该窗口接待顾客数目增加1
            cus_id++;//到下一个顾客
        }
        else
        {
            isfree[QW.top().id]=true;
            curtime=QW.top().time;//当前时间点来到刚刚完成一位顾客的时间点
            QW.pop();
        }
    }
    while(!QW.empty())//如果还有正在进行服务的窗口,不断更新当前时间点
    {
        curtime=QW.top().time;
        QW.pop();
    }
    int Max=-1,sum=0;
    for(int i=0; i<num1; i++)
    {
        Max=max(Max,v[i].wait_time);//找出每个人的最长等待时间
        sum+=v[i].wait_time;
    }
    cout<<setprecision(1)<<fixed<<(double)sum/num1<<" "<<Max<<" "<<curtime<<endl;
    for(int i=0; i<num2; i++)
    {
        if(i==0)
            cout<<win_num[i];
        else
            cout<<" "<<win_num[i];
    }
    delete[]isfree;
    delete[]win_num;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值