1017 Queueing at Bank (25分)
注意是求平均等待时间,而不是周转时间(受本学期os影响+_+)
这题大有文章(其实是寒假在家做题效率太低QAQ)
对\(k\)个窗口分别维护对应的最早空闲时间,只要窗口一空闲即可安排顾客。
可以采用小根堆来维护,保证小根堆里的元素始终只有\(k\)个,每次出队的窗口即为当前窗口的最早空闲时间。
对每个顾客:
- 若当前出队的窗口空闲,将当前窗口的空闲时间更新为\(a[i].arrive\_time+a[i].serve\_time\)
- 若当前出队的窗口非空闲,则需等待,将当前窗口的空闲时间更新为\(heap.top()+a[i].serve\_time\)
注意:
- 银行营业时间是\(8:00:00\)到\(17:00:00\)
- 每个客户最多只能服务\(60min\),\(PAT\)数据貌似没体现这一点,\(AcWing\)数据是有体现的
- 只要客户在\(17:00:00\)之前排上队,则即使办理业务时超过\(17:00:00\),也会被服务
const int N=10010;
struct Customer {
int hh,mm,ss;
int arrive_time;
int serve_time;
bool operator<(const Customer &W) const
{
return arrive_time<W.arrive_time;
}
}a[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
scanf("%d:%d:%d %d",&a[i].hh,&a[i].mm,&a[i].ss,&a[i].serve_time);
a[i].serve_time=min(a[i].serve_time,60);
a[i].arrive_time=a[i].hh*3600+a[i].mm*60+a[i].ss;
}
sort(a,a+n);
priority_queue<int,vector<int>,greater<int> > heap;
for(int i=0;i<m;i++) heap.push(8*3600);
int res=0,cnt=0;
for(int i=0;i<n;i++)
{
int t=heap.top();
heap.pop();
if(a[i].arrive_time > 17*3600) break;
if(a[i].arrive_time >= t)
heap.push(a[i].arrive_time+a[i].serve_time*60);
else
{
res+=t-a[i].arrive_time;
heap.push(t+a[i].serve_time*60);
}
cnt++;
}
if(!cnt) puts("0.0");
else printf("%.1f\n",res/60.0/cnt);
//system("pause");
return 0;
}