zoukankan      html  css  js  c++  java
  • 7-5 银行排队问题之单队列多窗口服务 (25 分)

    题目:

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

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

    输入格式:

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

    输出格式:

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

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

    思路:

    设两个结构体分别表示窗口和客户。每个窗口有他的服务人数和处理完当前客户后的结束时间。两重循环每个客户遍历所有的窗口,分等待和不等两种情况讨论。

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <malloc.h>
    #define inf  -1e9
    #define FRE() freopen("in.txt","r",stdin)
    using namespace std;
    const int maxn = 1010;
    struct Windows
    {
        int num_people;
        int endTime;
        Windows()
        {
            num_people = 0, endTime = 0;
        }
    } w[15];
    struct People
    {
        int arrive;
        int wait;
        int keep;
    } peo[maxn];
    int N,K,l,r;
    
    void init()
    {
        l = 0,r = 0;
        scanf("%d",&N);
        for(int i = 0; i<N; i++)
        {
            scanf("%d%d",&peo[r].arrive,&peo[r].keep);
            if(peo[r].keep>60)
                peo[r].keep = 60;
            peo[r].wait = 0;
            r++;
        }
        scanf("%d",&K);
        for(int i = 0; i<K; i++)
        {
            w[i].endTime = 0;
            w[i].num_people = 0;
        }
    }
    
    void check()
    {
        for(int i = 0; i<N; i++)
        {
            printf("%d ",peo[i].keep);
        }
        printf("
    ");
    }
    
    
    int main()
    {
       // FRE();
        int maxWite = 0,sumWite = 0,lastFinish = 0;
        init();
        while(l<r)
        {
            bool isWait = true;
            int index = -1,minEnd = 1e9;
            for(int i = 0; i<K; i++)
            {
                if(peo[l].arrive>=w[i].endTime)//不需要等待
                {
                    w[i].endTime = peo[l].arrive+peo[l].keep;//更新该窗口的结束时间
                    w[i].num_people++;//更新该窗口的服务人数
                    isWait = false;//标记一下该客户不需要等待
                    break;
                }
                else //需要等待
                {
                    if(minEnd > w[i].endTime)//找到结束时间最近的窗口
                    {
                        minEnd = w[i].endTime;//更新最近的结束时间
                        index = i;//记录这个窗口的下标
                    }
                }
            }
            if(isWait)
            {
                peo[l].wait += w[index].endTime-peo[l].arrive;//更新客户的等待时间
                sumWite += w[index].endTime-peo[l].arrive;//求所有客户的等待时间的总和
                maxWite = max(maxWite, w[index].endTime-peo[l].arrive);//更新最大的等待时间
                w[index].endTime += peo[l].keep;//更新该窗口的结束时间
                w[index].num_people++;//更新该窗口的服务人数
            }
            l++;
        }
        //check();
        for(int i = 0; i<K; i++)
        {
            if(w[i].endTime>lastFinish)
                lastFinish = w[i].endTime;
        }
        printf("%.1f %d %d
    ",sumWite*1.0/N, maxWite, lastFinish);
        for(int i = 0; i<K; i++)
        {
            if(i!=0)
                printf(" ");
            printf("%d",w[i].num_people);
        }
        return 0;
    }
    /*
    9
    0 20
    1 15
    1 61
    2 10
    10 5
    10 3
    30 18
    31 25
    31 2
    3
    */
    /*
    6.2 17 61
    5 3 1
    */
    View Code
  • 相关阅读:
    wustctf2020_name_your_dog
    wdb2018_guess(stack smash,__environ获取栈变量)
    ciscn_2019_en_3
    植物大战僵尸逆向(秒杀僵尸)
    pwnable_hacknote
    pwn-hitcontraining_magicheap(unsorted bin attack)
    pwn-[XMAN]level5(通用gadget,mprotect)
    pwn-pwnable_orw(seccomp&orw)
    《心流》有感
    LC112 路径总和
  • 原文地址:https://www.cnblogs.com/sykline/p/9816874.html
Copyright © 2011-2022 走看看