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

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

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

输入格式:

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

输出格式:

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

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

输入样例:

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


因为之前一段时间的懒惰,好久没有用功学习并且更新博客了,现在开始重新更新博客。

这道题很好玩,因为需要模拟银行的进程所以需要用栈的知识来模拟,但是因为窗口数目的不确定性所以不能确定需要的栈的个数,这是一个需要解决的点。

还有一点就是对数据的处理,如何处理并得到各个客户处理业务的信息这是最有意思的一个点。

我通过构建两个类来分别模拟客户和窗口,用客户类的数据元素来处理看似没有关系的信息并将其联系起来。用窗口类来模拟栈的作用。

本题的重点就是如何通过对时间的处理来模拟银行进程

下附代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct
{
    double start;
    double ends;
    double wait;
}Person;

typedef struct
{
    int num;
    Person List[1005];
}Window;

int main()
{
    int n, k;
    double s, e, time = 0, Min_time = 0, Maxtime = 0;
    Window all[15];
    Person store[10000];
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%lf %lf", &s, &e);
        if(e > 60){e = 60;}
        store[i].start = s, store[i].ends = e + s;
    }
    scanf("%d", &k);
    for(int i = 0 ; i < k; i++)
    {
        all[i].num = 0;
        all[i].List[0].ends = 0;
    }
    for(int i = 0; i < n; i++)
    {
        double mintime = 0;
        int place = 0;
        for(int j = 0; j < k; j++)
        {
            if(!j)
            {
                int num = all[j].num - 1;
                mintime = all[j].List[num].ends - store[i].start;
                if(mintime < 0)
                {
                    mintime = 0;
                }
                place = j;
                //printf("%lf %d %lf\n", mintime, all[j].List[num].ends - store[i].start, place);
                //printf("%lf %lf\n", all[j].List[num].ends, store[i].start);
            }
            else
            {
                int num = all[j].num - 1;
                double time = all[j].List[num].ends - store[i].start;
                if(time < 0)
                {
                    time = 0;
                }
                if(mintime > time)
                {
                    mintime = time;
                    place  = j;
                }
                //printf("++%lf %d %lf\n", mintime, all[j].List[num].ends - store[i].start, place);
                //printf("%lf %lf\n", all[j].List[num].ends, store[i].start);
            }
            //printf("%lf %d\n", mintime, place);
        }

        int num = all[place].num;

        all[place].num++;
        //printf("%d %d\n", place, all[place].num);
        all[place].List[num].start = store[i].start + mintime;

        all[place].List[num].wait = mintime;

        all[place].List[num].ends = store[i].ends + mintime;
        //printf("%lf %lf\n", all[place].List[num].ends, all[place].List[num].start);

        if(!i)
        {
            Min_time = mintime;
            Maxtime = store[i].ends + mintime;
        }
        else
        {
            if(mintime > Min_time)
            {
                Min_time = mintime;
            }
            if(Maxtime < store[i].ends + mintime)
            {
                Maxtime = store[i].ends + mintime;
            }
        }
        time += mintime;
    }
    printf("%.1lf %.lf %.lf\n", time / n, Min_time, Maxtime);
    for(int i = 0; i < k; i++)
    {
        if(i)
        {
            printf(" ");
        }
        printf("%d", all[i].num);
    }
    printf("\n");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值