1. 程式人生 > >7-4 銀行排隊問題之單視窗“夾塞”版 (30 分)

7-4 銀行排隊問題之單視窗“夾塞”版 (30 分)

7-4 銀行排隊問題之單視窗“夾塞”版 (30 分)

排隊“夾塞”是引起大家強烈不滿的行為,但是這種現象時常存在。在銀行的單視窗排隊問題中,假設銀行只有1個視窗提供服務,所有顧客按到達時間排成一條長龍。當視窗空閒時,下一位顧客即去該視窗處理事務。此時如果已知第i位顧客與排在後面的第j位顧客是好朋友,並且願意替朋友辦理事務的話,那麼第i位顧客的事務處理時間就是自己的事務加朋友的事務所耗時間的總和。在這種情況下,顧客的等待時間就可能被影響。假設所有人到達銀行時,若沒有空視窗,都會請求排在最前面的朋友幫忙(包括正在視窗接受服務的朋友);當有不止一位朋友請求某位顧客幫忙時,該顧客會根據自己朋友請求的順序來依次處理事務。試編寫程式模擬這種現象,並計算顧客的平均等待時間。

輸入格式:

輸入的第一行是兩個整數:1≤N≤10000,為顧客總數;0≤M≤100,為彼此不相交的朋友圈子個數。若M非0,則此後M行,每行先給出正整數2≤L≤100,代表該圈子裡朋友的總數,隨後給出該朋友圈裡的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 <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define lowbit(x) (x&(-x))
#define mem(a,b) memset(a,b,sizeof(a))
#define FRER() freopen("in.txt","r",stdin);
#define FREW() freopen("out.txt","w",stdout);
using namespace std;
const int maxn = 10000 + 7;
map<string,int>mmp;
struct Node{
    string name;
    int t,p;
}nodes[maxn];
bool vis[maxn];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        int nn;
        scanf("%d",&nn);
        for(int j=0;j<nn;j++){
            string name;
            cin>>name;
            mmp[name] = i+1;
        }
    }
    int tot = m+1;
    for(int i=0;i<n;i++){
        cin>>nodes[i].name>>nodes[i].t>>nodes[i].p;
        if(!mmp[nodes[i].name]) mmp[nodes[i].name] = tot++;
        if(nodes[i].p>60) nodes[i].p = 60;
    }
    int ans = 0 , time = nodes[0].t+nodes[0].p;
    queue<Node>q;
    q.push(nodes[0]);
    vis[0] = true;
    while(!q.empty()){
        Node now = q.front();
        cout<<now.name<<endl;
        q.pop();
        bool flag = false;
        for(int i=1;i<n;i++){
            if(vis[i]) continue;
            if(nodes[i].t>time) break;
            if(mmp[nodes[i].name]==mmp[now.name]){
                q.push(nodes[i]);
                vis[i] = true;
                flag = true;
                ans += time - nodes[i].t;
                time += nodes[i].p;
                break;
            }
        }
        if(!flag){
            for(int i=1;i<n;i++){
                if(vis[i]) continue;
                q.push(nodes[i]);
                vis[i] = true;
                ans += max(0,time - nodes[i].t);
                if(nodes[i].t>time) time = nodes[i].t;
                time+=nodes[i].p;
                break;
            }
        }
    }
    printf("%.1f",1.0*ans/n);
}