習題8.1 銀行排隊問題之單隊列多窗口服務 (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

注意一點,題目說有多個窗口可選擇時,選編號最小的,time數組記錄窗口服務完客戶后的時間,num記錄服務過的人數,實時更新,當一個人面臨很多窗口的time都比他到達的時間少時,應當把這些窗口的time先改成他的到達時間,這樣在優先隊列中會優先選擇編號最小的。
代碼:
#include <cstdio>
#include <queue>
using namespace std;

int n,k;
int c[1000][2];
int time[10],num[10],wt,mwt,ct;
struct cmp {
    bool operator()(const int &a,const int &b) const {
        if(time[a] == time[b]) return a > b;
        return time[a] > time[b];
    }
};
int main() {
    scanf("%d",&n);
    for(int i = 0;i < n;i ++) {
        scanf("%d%d",&c[i][0],&c[i][1]);
        if(c[i][1] > 60) c[i][1] = 60;
    }
    scanf("%d",&k);
    priority_queue<int,vector<int>,cmp> q;
    for(int i = 0;i < k;i ++) {
        q.push(i);
    }
    for(int i = 0;i < n;i ++) {
        while(time[q.top()] < c[i][0]) {
            int d = q.top();
            q.pop();
            time[d] = c[i][0];
            q.push(d);
        }
        int d = q.top();
        q.pop();
        num[d] ++;
        if(time[d] > c[i][0]) {
            wt += time[d] - c[i][0];
            mwt = max(mwt,time[d] - c[i][0]);
        }
        time[d] = max(time[d],c[i][0]) + c[i][1];
        ct = max(ct,time[d]);
        q.push(d);
    }
    printf("%.1f %d %d\n",wt * 1.0 / n,mwt,ct);
    for(int i = 0;i < k;i ++) {
        if(i) putchar(' ');
        printf("%d",num[i]);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM