有n個客戶和k個窗口,給出n個客戶的到達時間和需要的時長
有空閑的窗口就去辦理,沒有的話就需要等待,求客戶的平均時長。
如果在8點前來的,就需要等到8點。
如果17點以后來的,則不會被服務,無需考慮。
按客戶的到達時間排序
建立一個優先級隊列,一開始放入k個窗口,初始結束時間為8*3600
然后for循環客戶,每次從優先級隊列中取出最早結束時間的窗口
如果客戶比結束時間來的早,就需要等待
如果客戶比結束時間來的晚,就無需等待
最后只要統計那些到達時間在17*3600之前的客戶即可。

#include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cstring> using namespace std; const int maxn=10000; int n,k; struct Customer{ int arrive; //到達時間 int process; //服務時間 int start; //客戶開始被服務的時間 int finish; //客戶的結束時間 int wait; //客戶的等待時間 bool operator<(const Customer tmp)const{ return arrive<tmp.arrive; } }cus[maxn]; struct Window{ int finish_time; bool operator<(const Window tmp)const{ return finish_time>tmp.finish_time; } }; int main() { int h,m,s,t; scanf("%d %d",&n,&k); for(int i=0;i<n;i++){ scanf("%d:%d:%d %d",&h,&m,&s,&t); cus[i].arrive=h*3600+m*60+s; if(t>60) t=60; //樣例中其實也沒有超過60分鍾的數據,題目說了是假設 cus[i].process=t*60; } priority_queue<Window>q; Window w; for(int i=0;i<k;i++){ w.finish_time=8*3600; q.push(w); } sort(cus,cus+n); Window ww; for(int i=0;i<n;i++){ w=q.top(); q.pop(); if(cus[i].arrive<w.finish_time){ cus[i].wait=w.finish_time-cus[i].arrive; cus[i].start=w.finish_time; cus[i].finish=cus[i].start+cus[i].process; ww.finish_time=cus[i].finish; q.push(ww); } else{ cus[i].start=cus[i].arrive; cus[i].wait=0; cus[i].finish=cus[i].start+cus[i].process; ww.finish_time=cus[i].finish; q.push(ww); } } double sum=0; int cnt=0; for(int i=0;i<n;i++){ /* 一開始和P1014搞混了,以為如果是17點之前還沒被服務,就不考慮 后來發現題目中明確說了,是17點之后到的才不考慮 */ if(cus[i].arrive<=17*3600){ sum+=cus[i].wait; cnt++; } } if(cnt==0) printf("0.0\n"); //去掉這個也能AC,說明樣例沒有出現cnt為0的情況 else{ double minutes=sum/60.0/cnt; printf("%.1lf\n",minutes); } return 0; }