1. 程式人生 > >PTA 銀行排隊問題之單隊列多窗口加VIP服務 隊列+模擬

PTA 銀行排隊問題之單隊列多窗口加VIP服務 隊列+模擬

-html people 分隔 mda max 不能 ram 輸入 空格

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

有些銀行會給VIP客戶以各種優惠服務,例如專門開辟VIP窗口。為了最大限度地利用資源,VIP窗口的服務機制定義為:當隊列中沒有VIP客戶時,該窗口為普通顧客服務;當該窗口空閑並且隊列中有VIP客戶在等待時,排在最前面的VIP客戶享受該窗口的服務。同時,當輪到某VIP客戶出列時,若VIP窗口非空,該客戶可以選擇空閑的普通窗口;否則一定選擇VIP窗口。

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

輸入格式:

輸入第1行給出正整數N(≤),為顧客總人數;隨後N行,每行給出一位顧客的到達時間T、事務處理時間P和是否VIP的標誌(1是VIP,0則不是),並且假設輸入數據已經按到達時間先後排好了順序;最後一行給出正整數K(≤)—— 為開設的營業窗口數,以及VIP窗口的編號(從0到K1)。這裏假設每位顧客事務被處理的最長時間為60分鐘。

輸出格式:

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

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

輸入樣例:

10
0 20 0
0 20 0
1 68 1
1 12 1
2 15 0
2 10 0
3 15 1
10 12 1
30 15 0
62 5 1
3 1

輸出樣例:

15.1 35 67
4 5 1

調了整整一下午,真的惡心,註意看清加粗字體的要求,用隊列模擬就行了,因為之前用結構體寫過好幾次隊列了,這次就偷懶直接用STL裏的了,代碼如下(因為網上代碼多是用時間流逝模擬,所以貼出我的代碼以供交流學習,還望不要抄襲作業,畢竟可能會查重的:
  1 #include <iostream>
  2 #include <cstdio>
  3
#include <algorithm> 4 #include <cstring> 5 #include <queue> 6 7 using namespace std; 8 9 #define INF 0x3f3f3f3f 10 11 const int maxn = 1000 + 5; 12 13 struct people { 14 int T, P, VIP, counter_id; 15 }Customer[maxn]; 16 17 int main() 18 { 19 int n; 20 scanf("%d", &n); 21 for(int i = 0; i < n; ++i) { 22 scanf("%d %d %d", &Customer[i].T, &Customer[i].P, &Customer[i].VIP); 23 Customer[i].P = min(Customer[i].P, 60); 24 } 25 26 int K, vipK; 27 scanf("%d %d", &K, &vipK); 28 29 bool vis[maxn] = {0}; 30 31 queue<people> q; 32 33 bool ok = true; 34 35 for(int i = 0; i < n; ++i) { 36 if(Customer[i].T > 0) 37 break; 38 if(Customer[i].VIP) { 39 ok = false; 40 Customer[i].counter_id = vipK; 41 vis[i] = 1; 42 q.push(Customer[i]); 43 break; 44 } 45 } 46 47 if(ok) { 48 Customer[0].counter_id = 0; 49 vis[0] = 1; 50 q.push(Customer[0]); 51 } 52 53 int sum = 0, _max = 0, last = 0, now = 0; 54 int windows[15] = {0}, num_windows[15] = {0}; 55 56 while(!q.empty()) { 57 _max = max(_max, windows[q.front().counter_id] - q.front().T); 58 sum += max(0, windows[q.front().counter_id] - q.front().T); 59 windows[q.front().counter_id] = max(windows[q.front().counter_id], q.front().T) + q.front().P; 60 last = max(last, windows[q.front().counter_id]); 61 ++num_windows[q.front().counter_id]; 62 63 int minn = INF, idx = 0; 64 65 for(int i = 0; i < K; ++i) { 66 if(windows[i] < minn) { 67 minn = windows[i]; 68 idx = i; 69 } 70 } 71 72 while(now < n && vis[now]) 73 ++now; 74 if(now == n) 75 break; 76 77 ok = true; 78 79 if(Customer[now].T <= windows[idx]) { 80 ok = true; 81 if(idx == vipK || windows[idx] == windows[vipK]) { 82 for(int i = now; i < n; ++i) { 83 if(!vis[i]) { 84 if(Customer[i].T > windows[idx]) { 85 break; 86 } 87 if(Customer[i].VIP) { 88 ok = false; 89 Customer[i].counter_id = vipK; 90 q.push(Customer[i]); 91 vis[i] = 1; 92 break; 93 } 94 } 95 } 96 } 97 if(ok) { 98 Customer[now].counter_id = idx; 99 q.push(Customer[now]); 100 vis[now] = 1; 101 } 102 } 103 else { 104 if(Customer[now].VIP && windows[vipK] <= Customer[now].T) { 105 Customer[now].counter_id = vipK; 106 q.push(Customer[now]); 107 vis[now] = 1; 108 } 109 else { 110 for(int i = 0; i < K; ++i) { 111 if(windows[i] <= Customer[now].T) { 112 Customer[now].counter_id = i; 113 q.push(Customer[now]); 114 vis[now] = 1; 115 break; 116 } 117 } 118 } 119 } 120 q.pop(); 121 } 122 123 printf("%.1f %d %d\n", sum * 1.0 / n, _max, last); 124 125 for(int i = 0; i < K; ++i) { 126 printf("%d%c", num_windows[i], i == K - 1 ? \n : ); 127 } 128 129 return 0; 130 }

PTA 銀行排隊問題之單隊列多窗口加VIP服務 隊列+模擬