1. 程式人生 > >1017 Queueing at Bank (25 分)【模擬】

1017 Queueing at Bank (25 分)【模擬】

Suppose a bank has K windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. All the customers have to wait in line behind the yellow line, until it is his/her turn to be served and there is a window available. It is assumed that no window can be occupied by a single customer for more than 1 hour.

Now given the arriving time T and the processing time P of each customer, you are supposed to tell the average waiting time of all the customers.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 numbers: N (≤10​4​​) - the total number of customers, and K (≤100) - the number of windows. Then N lines follow, each contains 2 times: HH:MM:SS

 - the arriving time, and P - the processing time in minutes of a customer. Here HH is in the range [00, 23], MM and SS are both in [00, 59]. It is assumed that no two customers arrives at the same time.

Notice that the bank opens from 08:00 to 17:00. Anyone arrives early will have to wait in line till 08:00, and anyone comes too late (at or after 17:00:01) will not be served nor counted into the average.

Output Specification:

For each test case, print in one line the average waiting time of all the customers, in minutes and accurate up to 1 decimal place.

Sample Input:

7 3
07:55:00 16
17:00:01 2
07:59:59 15
08:01:00 60
08:00:00 30
08:00:02 2
08:03:00 10

Sample Output:

8.2

 題意:有k個視窗,按照先後的順序輪流到空的視窗服務,銀行8點上班17點下班,一旦過了17點並不服務,最後我們要求出每個顧客wait的時間

解題思路:用一個結構儲存已秒為單位的來的時間和處理的時間,我們只將符合的時間的顧客壓入customer陣列中,然後按照來的時間排序,接下來關鍵的就是找出結束最早的視窗,用2個迴圈為每個顧客找到結束最早的視窗,並更新視窗,這裡的視窗用vector初始化為28800,也就是8點,每一個外迴圈更新一次window,如果視窗結束的時間比顧客來的時間還早就有wait時間,最後算平均的時間除以60再除以符合的顧客數量,這裡還需要注意一點的是如果一個符合的都沒有也就是0,除數不能為0,就要特別判斷輸出0.0就好了。

#include<bits/stdc++.h>
using namespace std;
struct bank{
	int coming,processing;
};
bool cmp(bank a,bank b)//將符合的顧客按照來的先後排序
{
	return a.coming<b.coming;
}
int main(void)
{
    int n,k,h,m,s,p;
    scanf("%d %d",&n,&k);
    vector<bank>customer;
    for(int i=0;i<n;i++)
    {
    	scanf("%d:%d:%d %d",&h,&m,&s,&p);
    	int temp=h*3600+m*60+s;
    	if(temp>61200) continue;//篩選符合的條件
    	customer.push_back({temp,p*60});
	}
	sort(customer.begin(),customer.end(),cmp);
	vector<int>window(k,28800);//直接將視窗初始為28800秒即8點
	double result=0;
	for(int i=0;i<customer.size();i++)
	{
		int mindex=0,minfinish=window[0];
        //找出最先結束的視窗
		for(int j=1;j<k;j++)
		{
			if(window[j]<minfinish)
			{
				mindex=j;
				minfinish=window[j];
			}
		}
        //更新window的值並將如果需要wait的加起來
	    if(window[mindex]<=customer[i].coming)
		{
			window[mindex]=customer[i].coming+customer[i].processing;
		}	
		else
		{
			result+=(window[mindex]-customer[i].coming);
			window[mindex]+=customer[i].processing;
		}
	}
    if(customer.size()==0) printf("0.0\n");
    else printf("%.1lf\n",result/60/customer.size());
	return 0;
}