zoukankan      html  css  js  c++  java
  • 习题8.3 银行排队问题之单窗口“夹塞”版 (30分)

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

    输入格式:

    输入的第一行是两个整数:1,为顾客总数;0,为彼此不相交的朋友圈子个数。若M非0,则此后M行,每行先给出正整数2,代表该圈子里朋友的总数,随后给出该朋友圈里的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 <cstdio>
    #include <queue>
    #include <map>
    using namespace std;
    
    struct peo {
        char name[4];
        int T,P;
    }p[10000];
    int ans[10000],c;
    int n,m,l,num,ptime;
    double w;
    int f[10001],vis[10001];
    char name[4];
    map<string,int> mp;
    int main() {
        scanf("%d%d",&n,&m);
        while(m --) {
            scanf("%d",&l);
            for(int i = 0;i < l;i ++) {
                scanf("%s",name);
                f[mp[name] = ++ num] = m + 1;//由于不同圈子没有交集  所以不用并查集 用数组标记是否是同一个圈子
            }
        }
        for(int i = 0;i < n;i ++) {
            scanf("%s%d%d",p[i].name,&p[i].T,&p[i].P);
            if(p[i].P > 60) p[i].P = 60;
        }
        int i = 0;
        while(i < n) {
            while(i < n && vis[i]) i ++;
            int d = f[mp[p[i].name]],j = i;
            if(i >= n) break;
            do {//这里这个循环是这样的  如果说第一个人在办理业务 后边有朋友 可以同时帮着办了  所谓等待时间就是从到达到自己的业务被着手处理等的时间 只要第一个人还在办理 后边来的朋友都可以交给他处理 除非他走了
                if(vis[j] || f[mp[p[j].name]] != d) {
                    j ++;
                    continue;
                }
                w += max(0,ptime - p[j].T);
                ans[c ++] = j;
                ptime = max(ptime,p[j].T) + p[j].P;
                vis[j ++] = 1;
            }
            while(d && j < n && p[j].T <= ptime);
        }
        for(int i = 0;i < n;i ++) {
            printf("%s
    ",p[ans[i]].name);
        }
        printf("%.1f",w / n);
    }
  • 相关阅读:
    ionic入门之AngularJS扩展基本布局
    ionic入门之AngularJS扩展(一)
    test
    面试题小整理
    使用Code first 进行更新数据库结构(数据迁移)
    SQL模糊查询与删除多条语句复习
    GridView 根据要求显示指定值
    个人工作记录---工作中遇到的sql查询语句解析
    数据库,inner join,left join right join 的区别
    利用set实现去重
  • 原文地址:https://www.cnblogs.com/8023spz/p/12288782.html
Copyright © 2011-2022 走看看