7-6 银行排队问题之单队列多窗口加VIP服务 (30 分)

 

7-6 银行排队问题之单队列多窗口加VIP服务 (30 分)

假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙。当有窗口空闲时,下一位顾客即去该窗口处理事务。当有多个窗口可选择时,假设顾客总是选择编号最小的窗口。

有些银行会给VIP客户以各种优惠服务,例如专门开辟VIP窗口。为了最大限度地利用资源,VIP窗口的服务机制定义为:当队列中没有VIP客户时,该窗口为普通顾客服务;当该窗口空闲并且队列中有VIP客户在等待时,排在最前面的VIP客户享受该窗口的服务。同时,当轮到某VIP客户出列时,若VIP窗口非空,该客户可以选择空闲的普通窗口;否则一定选择VIP窗口

本题要求输出前来等待服务的N位顾客的平均等待时间、最长等待时间、最后完成时间,并且统计每个窗口服务了多少名顾客。

输入格式:

输入第1行给出正整数N(≤1000),为顾客总人数;随后N行,每行给出一位顾客的到达时间T、事务处理时间P和是否VIP的标志(1是VIP,0则不是),并且假设输入数据已经按到达时间先后排好了顺序;最后一行给出正整数K(≤10)—— 为开设的营业窗口数,以及VIP窗口的编号(从0到K−1)。这里假设每位顾客事务被处理的最长时间为60分钟。

输出格式:

在第一行中输出平均等待时间(输出到小数点后1位)、最长等待时间、最后完成时间,之间用1个空格分隔,行末不能有多余空格。

在第二行中按编号递增顺序输出每个窗口服务了多少名顾客,数字之间用1个空格分隔,行末不能有多余空格。

输入样例:

10
0 20 0
0 20 0
1 68 1
1 12 1
2 15 0
2 10 0
3 15 1
10 12 1
30 15 0
62 5 1
3 1

输出样例:

15.1 35 67
4 5 1
#define FRER() freopen("in.txt","r",stdin)
#define FREW() freopen("out.txt","w",stdout)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <stack>
#include <set>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;

struct window{
    int cnt;
    int t;
    window(){
        cnt = t = 0;
    }
}w[17];
struct person{
    int id;
    int vip;
    int c,p;
    int vis;
    person(){
        c = p = vip = vis = 0;
    }
}p[1007];
queue<person>q;
int main(){
    int n,k,vip;
    int tot_time,max_time,last_time;
    tot_time = max_time = last_time = 0;
    cin>>n;
    int l=1,r=n;
    for(int i=1;i<=n;i++){
        cin>>p[i].c>>p[i].p>>p[i].vip;
        p[i].p=p[i].p>60?60:p[i].p;
        p[i].id = i;
        if(p[i].vip){
            q.push(p[i]);
        }
    }
    cin>>k>>vip;vip++;
    while(l<=r){
        person& now = p[l];
        if(now.vis){l++;continue;}
        //cout<<l<<endl;
        bool flag = false;
        if(now.vip){
            if(w[vip].t<=now.c){
                w[vip].cnt++;
                w[vip].t = now.c+now.p;
                p[now.id].vis = 1;
                l++;
                q.pop();
                flag = true;
            }
        }
        if(!flag){
            bool sign = false;
            int ppos=0;
            for(int j=1;j<=k;j++){
                if(w[j].t<=now.c){
                    sign = true;
                    ppos = j;
                    break;
                }
            }
            if(sign){
                bool flag2 = false;
                if(ppos==vip&&!q.empty()){
                    person v = q.front();
                    if(v.c==p[l].c){
                        flag2 = true;
                        w[ppos].cnt++;
                        w[ppos].t=v.p+v.c;
                        p[v.id].vis = 1;
                        q.pop();
                        if(v.id==p[l].id)l++;
                    }
                }if(!flag2){
                    w[ppos].t = p[l].c+p[l].p;
                    w[ppos].cnt++;
                    p[l].vis = 1;
                    if(!q.empty()&&q.front().id==l){
                        q.pop();
                    }
                    l++;
                }
            }
            if(!sign){
                int min = 99999999;
                int pos = 0;
                for(int j=1;j<=k;j++){
                    if(w[j].t<min){
                        min = w[j].t;
                        pos = j;
                    }
                }
                
                bool flag3 = false;
                if(!q.empty()&&q.front().c<=min){
                    
                    person v = q.front();
                    if(vip==pos){
                        p[v.id].vis = 1;
                        tot_time += min - v.c;
                        w[pos].t += v.p;
                        w[pos].cnt++;
                        flag3 =true;
                        q.pop();
                        max_time = max(max_time,min-v.c);
                    }else if(w[vip].t==min){
                        flag3 = true;
                        p[v.id].vis = 1;
                        tot_time += min - v.c;
                        w[vip].t += v.p;
                        w[vip].cnt++;
                        q.pop();
                        if(v.id==l) l++;
                        max_time = max(max_time,min-v.c);
                    }
                }
                if(!flag3){
                    if(p[l].vip) q.pop();
                    tot_time += min - p[l].c;
                    w[pos].t += p[l].p;
                    w[pos].cnt++;
                    max_time = max(max_time,min-p[l].c);
                    l++;
                }
            }
        }
    }
    for(int i=1;i<=k;i++) last_time = max(last_time,w[i].t);
    printf("%.1f %d %d\n",1.0*tot_time/n,max_time,last_time);
    for(int i=1;i<=k;i++){
        printf("%d%c",w[i].cnt,i==k?'\n':' ');
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值