7-2 银行排队问题之单窗口“夹塞”版 (30分)

简介: 7-2 银行排队问题之单窗口“夹塞”版 (30分)

排队“夹塞”是引起大家强烈不满的行为,但是这种现象时常存在。在银行的单窗口排队问题中,假设银行只有1个窗口提供服务,所有顾客按到达时间排成一条长龙。当窗口空闲时,下一位顾客即去该窗口处理事务。此时如果已知第i位顾客与排在后面的第j位顾客是好朋友,并且愿意替朋友办理事务的话,那么第i位顾客的事务处理时间就是自己的事务加朋友的事务所耗时间的总和。在这种情况下,顾客的等待时间就可能被影响。假设所有人到达银行时,若没有空窗口,都会请求排在最前面的朋友帮忙(包括正在窗口接受服务的朋友);当有不止一位朋友请求某位顾客帮忙时,该顾客会根据自己朋友请求的顺序来依次处理事务。试编写程序模拟这种现象,并计算顾客的平均等待时间。


输入格式:

输入的第一行是两个整数:1≤N≤10000,为顾客总数;0≤M≤100,为彼此不相交的朋友圈子个数。若M非0,则此后M行,每行先给出正整数2≤L≤100,代表该圈子里朋友的总数,随后给出该朋友圈里的L位朋友的名字。名字由3个大写英文字母组成,名字间用1个空格分隔。最后N行给出N位顾客的姓名、到达时间T和事务处理时间P(以分钟为单位),之间用1个空格分隔。简单起见,这里假设顾客信息是按照到达时间先后顺序给出的(有并列时间的按照给出顺序排队),并且假设每个事务最多占用窗口服务60分钟(如果超过则按60分钟计算)。


输出格式:

按顾客接受服务的顺序输出顾客名字,每个名字占1行。最后一行输出所有顾客的平均等待时间,保留到小数点后1位。


输入样例:

6 2

3 ANN BOB JOE

2 JIM ZOE

JIM 0 20

BOB 0 15

ANN 0 30

AMY 0 2

ZOE 1 61

JOE 3 10


输出样例:

JIM

ZOE

BOB

ANN

JOE

AMY

75.2

#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
/*
 * 构建圈子
 * */
int cir1[10005];//每个圈子的人数
int cir11[10005];//打标记,
int cir22[10005] = {0};//打标记,就是看是否可以继续让下一个人用
string que1[10005];//输出的队列
string s1[105][105];//第一次的圈子,也就是原声圈子
string s2[105][105];//第二次输出的圈子,就是保存的结果
int cnt = 0,cnt1 = 0,cnt2 = 0;//备用计数器
int result = 0;//完成时间
double endTime = 0;
/*
 * 构建个人
 * */
struct Person{
    string name;
    int cir;//所在的圈子
    int arrive;
    int time;
}person[10005];
/*
 * 构建圈子的函数
 * */
void BuildCir(){
    int x;
    int count = 0;
    cin>>n>>m;
    for(int i = 0;i < m;i++){
        cin>>x;
        cir1[i] = x;//每个圈子有多少人
        for(int j = 0;j < x;j++){
            cin>>s1[i][j];//每个圈子里的具体的人数
        }
    }
}
/*
 * find 函数
 * */
int find(string name){
    for(int i = 0;i < m;i++){
        for(int j = 0;j < cir1[i];j++){ //cir1[i]表示这个圈子有多少人
            if(s1[i][j] == name){
                return i;
            }
        }
    }
    return -1;
}
int main(){
    BuildCir();//构建好圈子
    for(int i = 0;i < n;i++){
        cin>>person[i].name>>person[i].arrive>>person[i].time;
        if(person[i].time > 60)
            person[i].time = 60;
        person[i].cir = find(person[i].name);
    }//队列输入完毕
    int que[10005] = {0};//打标记,看看那个备选了  /*这个位置坑惨我了,天啊,一定要注意数据的范围啊*/
    for(int i = 0;i < n;i++){
        //cout<<person[i].name<<' '<<person[i].arrive<<' '<<person[i].time<<' '<<person[i].cir<<endl;
        if(person[i].cir != -1 && cir22[i] != 1 && que[i] == 0){  //是圈子里的人,但是圈子还没出现,并且人也没入队
            que1[cnt++] = person[i].name;//入队
            cir22[i] = 1;//圈子出现
            que[i] = 1;
            if(result >= person[i].arrive){//表示要排队等待
                endTime += result - person[i].arrive;
                //cout<<result <<'*'<< person[i].arrive<<endl;
                result += person[i].time;
                //cout<<endTime<<endl;
            }else {  //不需要排队等待
                result = person[i].arrive + person[i].time;
            }
            for(int j = i+1;j < n;j++){
                if(person[j].cir == person[i].cir){ //找同圈子里的人
                    if(person[j].arrive <= result){//这种情况下可以插队
                        endTime += result - person[j].arrive;
                        //cout<<result <<'*'<< person[j].arrive<<endl;
                        que1[cnt++] = person[j].name;
                        que[j] = 1;
                        result += person[j].time;
                        //cout<<endTime<<endl;
                    }else{//不能插队
                        cir22[i] = 0;//这个圈子拿出来重新排队
                        break;//不再继续往后找
                    }
                }
            }
        }else if(person[i].cir == -1){
            que1[cnt++] = person[i].name;//入队
            if(result >= person[i].arrive){//表示要排队等待
                endTime += result - person[i].arrive;
                //cout<<result <<'*'<< person[i].arrive<<endl;
                result += person[i].time;
                //cout<<endTime<<endl;
            }else {  //不需要排队等待
                result = person[i].arrive + person[i].time;
            }
        }
    }
    for(int i = 0;i < cnt;i++){
        cout<<que1[i]<<endl;
    }printf("%.1lf\n",endTime/n);
    return 0;
}
相关文章
考研真题)某银行提供了 1 个服务窗口和 10 个供顾客等待时使用的座位。顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号。取号机每次仅允许一位顾客使用。当营业员空闲时,通过叫号选取一位顾
考研真题)某银行提供了 1 个服务窗口和 10 个供顾客等待时使用的座位。顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号。取号机每次仅允许一位顾客使用。当营业员空闲时,通过叫号选取一位顾
淘宝批量复制宝贝提示“当前类目大于48小时发货的发货时间不能大于15天,请调整”怎么解决?
要复制这个宝贝上传到淘宝店铺,只需要重新复制一次,然后在大淘营淘宝宝贝复制专家下载配置的第二步,选择一个小于或等于15天的发货时间(见下图),这样就可以复制宝贝上传到淘宝店铺了。
|
SQL 存储 自然语言处理
晚上8点在地铁上收到boss需求:把400多张表的关系画出来明早客户要!
晚上8点在地铁上收到boss需求:把400多张表的关系画出来明早客户要!
115 0
晚上8点在地铁上收到boss需求:把400多张表的关系画出来明早客户要!
银行排队问题之单队列多窗口服务
银行排队问题之单队列多窗口服务
343 0
银行排队问题之单队列多窗口服务
SAP WM中阶明明设置了TO自动产生为啥冻结物料后没有TO单据产生?
SAP WM中阶明明设置了TO自动产生为啥冻结物料后没有TO单据产生?
SAP WM中阶明明设置了TO自动产生为啥冻结物料后没有TO单据产生?
7-46 银行排队问题之单队列多窗口服务 (10 分)
7-46 银行排队问题之单队列多窗口服务 (10 分)
347 0
7-45 银行业务队列简单模拟 (10 分)
7-45 银行业务队列简单模拟 (10 分)
181 0
|
存储 编译器 Linux
自义定类型详解——十分钟杀穿类型对齐机制
正片开始👀 结构大小👏 我们先随便给出一个结构体,为了计算他的大小,我给出完整的打印方案:
自义定类型详解——十分钟杀穿类型对齐机制
SAP QM 内向交货单包装的时候触发的检验批不能被自动取消?
SAP QM 内向交货单包装的时候触发的检验批不能被自动取消?
SAP QM 内向交货单包装的时候触发的检验批不能被自动取消?
|
存储 数据管理
SAP QM 内向交货单在完成包装之后就自动触发了检验批?
SAP QM 内向交货单在完成包装之后就自动触发了检验批?
SAP QM 内向交货单在完成包装之后就自动触发了检验批?