習題8.1 銀行排隊問題之單佇列多視窗服務
阿新 • • 發佈:2019-02-16
習題8.1 銀行排隊問題之單佇列多視窗服務(25 分)
假設銀行有K個視窗提供服務,視窗前設一條黃線,所有顧客按到達時間在黃線後排成一條長龍。當有視窗空閒時,下一位顧客即去該視窗處理事務。當有多個視窗可選擇時,假設顧客總是選擇編號最小的視窗。
本題要求輸出前來等待服務的N位顧客的平均等待時間、最長等待時間、最後完成時間,並且統計每個視窗服務了多少名顧客。
輸入格式:
輸入第1行給出正整數N(≤1000),為顧客總人數;隨後N行,每行給出一位顧客的到達時間T
和事務處理時間P
,並且假設輸入資料已經按到達時間先後排好了順序;最後一行給出正整數K(≤10),為開設的營業視窗數。這裡假設每位顧客事務被處理的最長時間為60分鐘。
輸出格式:
在第一行中輸出平均等待時間(輸出到小數點後1位)、最長等待時間、最後完成時間,之間用1個空格分隔,行末不能有多餘空格。
在第二行中按編號遞增順序輸出每個視窗服務了多少名顧客,數字之間用1個空格分隔,行末不能有多餘空格。
思路:
先通過輸入將佇列儲存在陣列中,之後用佇列頭元素的到達時間跟視窗的完成時間對比,因為題中說優先考慮近的視窗,所以可以遍歷視窗。如果隊首的到達時間比這個視窗的完成時間大,就不需要等待,更新這個視窗的等待時間,並且這個視窗人數加一,如果這個視窗無法服務,就求出這個視窗的最快完成時間。如果三個視窗都無法滿足,就需要等待,並且求出等待的時間並且用下表記錄。最後將需要等待的時間和完成的時間都記錄下來。最後將題目要求的資料輸出就行。
程式碼:
#include<stdio.h> #include<stdlib.h> typedef struct node { int t, p;//到達時間,處理時間 }ST; ST q[1005];//陣列模擬佇列 int main() { int l, r, n, k, i; while(~scanf("%d", &n)) { l = r = 0;//佇列頭和尾 for(i = 0; i < n; i++) { scanf("%d %d", &q[r].t, &q[r].p);//將輸入的數入佇列 if(q[r].p > 60) q[r].p = 60;//根據題目要求,最大處理時間60 r++; } scanf("%d", &k);//k個視窗 int sumwait = 0, lenwait = 0, wait = 0;//總的等待時間, 最長的等待時間, 單次等待時間 int sum[15] = {0}, winnum[15] = {0};//完成時間,視窗人數 while(l < r) { int flag = 0, minn = 99999, imin = 0;//標記變數, 最快的完成時間, 最快完成時間的下標 for(i = 0; i < k; i++)//遍歷k個視窗 { if(sum[i] < q[l].t)//如果佇列首位,到達時間比,完成時間大,就代表不需要等待 { sum[i] = q[l].t + q[l].p;//更新完成這個視窗完成的時間 winnum[i]++;//視窗人數加一 flag = 1;//標記一下,代表不需要等待 l++;//佇列首位除去 break;//退出迴圈 } if(minn > sum[i])//如果需要等待,就記錄各個窗口裡最快完成的那個視窗的完成時間,和下標 { minn = sum[i]; imin = i; } } if(!flag)//需要等待 { wait = minn - q[l].t;//等待的時間,最快完成的時間減去佇列第一個人到達的時間 if(lenwait < wait) lenwait = wait;//不斷更新等待的最長時間 sumwait += wait;//求等待時間的和 sum[imin] = minn + q[l].p;//更新對應視窗的完成時間 winnum[imin]++;//對應視窗人數++ l++;//佇列刪除首位 } } int last = 0; for(i = 0; i < k; i++) { if(last < sum[i]) last = sum[i];//求最大完成時間 } printf("%.1lf %d %d\n", 1.0 * sumwait / n, lenwait, last);//輸出,平均等待時間, 最長等待時間, 最後完成時間 for(i = 0; i < k; i++) { printf("%d", winnum[i]);//輸出各個視窗的人數 if(i == k - 1) printf("\n"); else printf(" "); } } return 0; }
聽講這道題的同學說著很簡單的一道題,做起來問題倒還是挺多的,這類題也是自己的短板之處,以後要多加練習。