7-5 銀行排隊問題之單隊列多窗口服務 (25 分)

題目:ios

假設銀行有K個窗口提供服務,窗口前設一條黃線,全部顧客按到達時間在黃線後排成一條長龍。當有窗口空閒時,下一位顧客即去該窗口處理事務。當有多個窗口可選擇時,假設顧客老是選擇編號最小的窗口。ide

本題要求輸出前來等待服務的N位顧客的平均等待時間、最長等待時間、最後完成時間,而且統計每一個窗口服務了多少名顧客。spa

輸入格式:code

輸入第1行給出正整數N(≤1000),爲顧客總人數;隨後N行,每行給出一位顧客的到達時間T和事務處理時間P,而且假設輸入數據已經按到達時間前後排好了順序;最後一行給出正整數K(≤10),爲開設的營業窗口數。這裏假設每位顧客事務被處理的最長時間60分鐘。blog

輸出格式:事務

在第一行中輸出平均等待時間(輸出到小數點後1位)、最長等待時間、最後完成時間,之間用1個空格分隔,行末不能有多餘空格。it

在第二行中按編號遞增順序輸出每一個窗口服務了多少名顧客,數字之間用1個空格分隔,行末不能有多餘空格。io

思路:ast

設兩個結構體分別表示窗口和客戶。每一個窗口有他的服務人數和處理完當前客戶後的結束時間。兩重循環每一個客戶遍歷全部的窗口,分等待和不等兩種狀況討論。class

代碼:

#include <iostream> #include <stdio.h> #include <malloc.h>
#define inf  -1e9
#define FRE() freopen("in.txt","r",stdin)
using namespace std; const int maxn = 1010; struct Windows { int num_people; int endTime; Windows() { num_people = 0, endTime = 0; } } w[15]; struct People { int arrive; int wait; int keep; } peo[maxn]; int N,K,l,r; void init() { l = 0,r = 0; scanf("%d",&N); for(int i = 0; i<N; i++) { scanf("%d%d",&peo[r].arrive,&peo[r].keep); if(peo[r].keep>60) peo[r].keep = 60; peo[r].wait = 0; r++; } scanf("%d",&K); for(int i = 0; i<K; i++) { w[i].endTime = 0; w[i].num_people = 0; } } void check() { for(int i = 0; i<N; i++) { printf("%d ",peo[i].keep); } printf("\n"); } int main() { // FRE();
    int maxWite = 0,sumWite = 0,lastFinish = 0; init(); while(l<r) { bool isWait = true; int index = -1,minEnd = 1e9; for(int i = 0; i<K; i++) { if(peo[l].arrive>=w[i].endTime)//不須要等待
 { w[i].endTime = peo[l].arrive+peo[l].keep;//更新該窗口的結束時間
                w[i].num_people++;//更新該窗口的服務人數
                isWait = false;//標記一下該客戶不須要等待
                break; } else //須要等待
 { if(minEnd > w[i].endTime)//找到結束時間最近的窗口
 { minEnd = w[i].endTime;//更新最近的結束時間
                    index = i;//記錄這個窗口的下標
 } } } if(isWait) { peo[l].wait += w[index].endTime-peo[l].arrive;//更新客戶的等待時間
            sumWite += w[index].endTime-peo[l].arrive;//求全部客戶的等待時間的總和
            maxWite = max(maxWite, w[index].endTime-peo[l].arrive);//更新最大的等待時間
            w[index].endTime += peo[l].keep;//更新該窗口的結束時間
            w[index].num_people++;//更新該窗口的服務人數
 } l++; } //check();
    for(int i = 0; i<K; i++) { if(w[i].endTime>lastFinish) lastFinish = w[i].endTime; } printf("%.1f %d %d\n",sumWite*1.0/N, maxWite, lastFinish); for(int i = 0; i<K; i++) { if(i!=0) printf(" "); printf("%d",w[i].num_people); } return 0; } /* 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 */
View Code
相關文章
相關標籤/搜索