PAT A1017 Queueing at Bank (25point(s))

Keywords: Windows

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
  • Idea: simulate the average waiting time of process scheduling in os
    step 1: push the customers who arrive before 17 o'clock into the queue customers, and arrange them in chronological order
    step 2: a priority queue is used to collect all windows. The windows are arranged according to the current end time (the earlier the end is, the higher the priority is)
    step 3: traverse customers, get the queue head of the window queue every time:
    case 1: if the arrival time of the current customer is longer than the end time of the first idle window, it means that there is no need to wait. When it comes, it is up: update window end time = the customer arrival time + required service time!
    case 2: if it is smaller than the end time of the current window (the best one) (it is full when the description comes), it needs to wait. 1. Update the end time of the window + = the service time required by the customer. 2. Accumulate the waiting time + = the end time of the window - the arrival time of the customer;

  • Pit point:

  1. Wrong 1: Example 1 2. It doesn't take into account that the window is always free when the customer comes

  2. Wrong 2: it's reasonable to say that if a person comes before 17 o'clock but the window is full, it will be invalid after 17 o'clock when the window is free, but the problem seems to be effective

  • code: normal Edition: algorithm notes
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110, INF = 0x3fffffff;
int end_time[maxn]; 
struct cus{
	int arrive_time, process_time;
	cus(int _arr, int _pro) : arrive_time(_arr), process_time(_pro){}
};
vector<cus> customers;
int GetTime(int h, int m, int s){
	return h * 3600 + m * 60 + s;
}
bool cmp(cus a, cus b){
	return a.arrive_time < b.arrive_time;
}
int main(){
	int num_cus, num_win;
	int open_time = GetTime(8, 0, 0), close_time = GetTime(17, 0, 1);
	scanf("%d %d", &num_cus, &num_win);
	for(int i = 0; i < num_cus; ++i){
		int th, tm, ts, tp;
		scanf("%d:%d:%d %d", &th, &tm, &ts, &tp);
		int t_time = GetTime(th, tm, ts);
		if(t_time < close_time){
			customers.push_back(cus(t_time, tp <= 60 ? tp * 60 : 3600));
		}
	}
	fill(end_time, end_time + maxn, open_time);
	sort(customers.begin(), customers.end(), cmp);
	int wait_time = 0;
	for(int i = 0; i < customers.size(); ++i){
		int now = -1, Min = INF;
		for(int j = 0; j < num_win; ++j){
			if(end_time[j] < Min){
				Min = end_time[j];
				now = j;
			}
		}	
		if(end_time[now] <= customers[i].arrive_time){
			end_time[now] = customers[i].arrive_time + customers[i].process_time; 
		}else{
			wait_time += (end_time[now] - customers[i].arrive_time);
			end_time[now] += customers[i].process_time;
		}	
	} 
	if(customers.size() == 0) printf("0.0");	//None in test data 
	else printf("%.1f", wait_time / 60.0 / customers.size());
	return 0;
} 

  • code: priority queue
#include <bits/stdc++.h>
using namespace std;
struct cus{
	int arrive_time, process_time;
	cus(int _arr, int _pro) : arrive_time(_arr), process_time(_pro){}
};
vector<cus> customers;
struct win{
	int id, end_time;
	win(int _id, int _et) : id(_id), end_time(_et){}
	bool operator < (const win & a) const {
		return end_time > a.end_time;
	}
};
priority_queue<win> pq;
int GetTime(int h, int m, int s){
	return h * 3600 + m * 60 + s;
}
bool cmp(cus a, cus b){
	return a.arrive_time < b.arrive_time;
}
int main(){
	int num_cus, num_win, open_time = GetTime(8, 0, 0), end_time = GetTime(17, 0, 1);
	scanf("%d %d", &num_cus, &num_win);
	for(int i = 0; i < num_cus; ++i){
		int th, tm, ts, tp;
		scanf("%d:%d:%d %d", &th, &tm, &ts, &tp);
		int t_time = GetTime(th, tm, ts);
		if(t_time < end_time){
			customers.push_back(cus(t_time, tp * 60));
		}
	}
	sort(customers.begin(), customers.end(), cmp);
	for(int i = 0; i < num_win; ++i){
		pq.push(win(i, open_time));	//Initialize window queue 
	}	
	int valid_cus = customers.size(), wait_time = 0;
	for(int i = 0; i < valid_cus; ++i){
		win now = pq.top();
//		If (now. End & time < end & time) {/ / Wrong 2: example 5 
			pq.pop();
//			cnt_served++;
			if(now.end_time <= customers[i].arrive_time){
				now.end_time = (customers[i].arrive_time + customers[i].process_time);
			}else{
				wait_time += (now.end_time - customers[i].arrive_time);	//Wrong 1: Example 1 2 if it ends earlier than the customer, he doesn't need to wait!! 
				now.end_time += customers[i].process_time;
			}
			pq.push(now); 
//		}
	} 
	if(valid_cus == 0) printf("0.0");	//None in test data 
	else printf("%.1f", wait_time / 60.0 / valid_cus);
	return 0;
} 

Published 271 original articles, won praise 5, visited 6342
Private letter follow

Posted by hstraf on Wed, 12 Feb 2020 01:26:46 -0800