数据结构—— 银行排队问题之单窗口“夹塞”版

本文介绍了一种模拟银行排队系统的算法,特别关注了朋友间的事务代理现象。通过建立顾客到达时间、事务处理时间和朋友圈子的数据结构,算法计算了每位顾客的等待时间,并最终得出平均等待时间。文章详细解释了代码实现过程,包括如何处理朋友请求和计算等待时间。
摘要由CSDN通过智能技术生成

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

一道模拟题,首先要里明白自己的思路,否则这道题会很难通过。
在这里说一点自己被坑的地方: 两人虽然同属一个圈子,但可能第一个人办完业务后,第二个人还没有达到,所以就不再考虑第二个人,让他去老老实实排队;

下面给出AC代码,附带一些必要的注释:

#include <bits/stdc++.h>

using namespace std;
const int maxn=10000+10;

struct node
{
    string name;
    int arrive,work;
}que[maxn];

int main()
{

    int n,m;  cin>>n>>m;


    vector<string>  friends[maxn];
    map<string, int> number; //记录每个圈子都有谁,vector的一维坐标代表第几个圈子

    for(int i=1;i<=m;i++)
    {
        int num; cin>>num;
        for(int j=0;j<num;j++)
        {
            string s; cin>>s;
            number[s]=i;
            friends[i].push_back(s);
        }
    }


    map<string,int> norder;//读入正常的顺序;

    for(int i=1;i<=n;i++)
    {
        string s;  int a,b; cin>>s>>a>>b;
        que[i].name=s,que[i].arrive=a,que[i].work= b>=60? 60 : b;
        norder[s]=i;
    }


    vector<int>  reorder[maxn];//记录每个圈子里各个人的先后顺序
    for(int i=1;i<=m;i++)
    {
        for(int j=0;j<friends[i].size();j++)
        {
            int x=norder[friends[i][j]];
            reorder[i].push_back(x);
        }

        sort(reorder[i].begin(),reorder[i].end());
    }


    bool vis[maxn]; memset(vis,false,sizeof(vis));
    int time=0,ans=0;

    for(int i=1;i<=n;i++)
    {
        if(vis[i]==true) continue;

        vis[i]=true;

        cout<<que[i].name<<endl;

        if(que[i].arrive>=time) time=que[i].work+que[i].arrive;
        else
        {
            ans+=time-que[i].arrive;
            time+=que[i].work;
        }

        int x=number[que[i].name];


        for(int j=0;j<reorder[x].size();j++)
        {
            int t=reorder[x][j];

            if(vis[t]==true) continue;

            if(que[t].arrive<=time)//如果一个圈子 第一个人办完了第二个人没到,就不进行考虑
            {
                vis[t]=true;
                ans+=time-que[t].arrive;
                time+=que[t].work;
                cout<<que[t].name<<endl;
            }

        }

    }


    printf("%.1f",ans*1.0/n);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值