1. 程式人生 > >資料結構—— 銀行排隊問題之單佇列多視窗服務

資料結構—— 銀行排隊問題之單佇列多視窗服務

題目大意:排隊“夾塞”是引起大家強烈不滿的行為,但是這種現象時常存在。在銀行的單視窗排隊問題中,假設銀行只有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;
}