PAT 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 (≤104) - the total number of customers, and K (≤100) - the number of windows. Then N lines follow, each contains 2 times: HH:MM:SS
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
題目大意: 銀行每天8:00整開始營業,17:00關門 。給出一些人到銀行的時間以及辦理業務所需時間。求每個人從到達銀行到開始辦理業務的平均等待時間。結果保留一位小數。
相似題 PAT 1014 題 解析傳送門:https://mp.csdn.net/postedit/84146442
注意: 1.凡17點以後到達銀行的不計入平均人數之內。
2.只要在17點以前到達銀行的不管銀行必須給與服務,即使開始服務時間超過17點。
3.凡在8點以前到的,必須等待到8點才能辦理業務,該等待時間算入等待時間之內
思路:1.銀行有多個視窗,用queue來模擬現實視窗,每個視窗只能有一個人
2.建立一個結構體,儲存每個人到銀行的時間,辦理業務所需時間,開始辦理時間,以及結束時間
3.由於涉及時分秒,因此將時間轉換為秒,並以該天零點為起始時間點
4.先將來銀行的所有人存入一個vector中,並按到達時間由小到大排序,然後從隊頭開始從陣列中選取一個人依次填入視窗。如果他人的到達時間小於8:00則將他的開始辦理時間記為8:00,否則將辦理時間記為到達時間,再將開始時間和業務所需時間相加得到結束時間
5.比較每個視窗的結束時間,選取最小結束時間的視窗,將正在等待的佇列的第一個取出排在該視窗並更新他的開始辦理時間以及結束時間(如果他的到達時間大於該視窗前一個人的結束時間,則開始辦理時間為到達時間,否則開始辦理時間為前一個人的結束時間)然後將該視窗的頭元素取出扔掉,使新加入的元素為正在辦理業務的人,從而保證每個視窗只有一個人。
6.將17:00以前到達的人的等待時間相加併除以人數,再換為分鐘的到結果。
坑點:凡17 點以前到達皆可被服務。
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<stdio.h>
using namespace std;
struct Person {
int arriveTime; //到達時間
int needTime; //辦理業務所需時間
int startTime; //開始服務時間
int endTime; //結束時間
};
//輸入函式
void input(vector<Person> &person, vector<queue<Person>>&que) {
int n, m;
cin >> n >> m;
que.resize(m); //給vector m個分配空間
for (int i = 0; i < n; i++) {
int H, M, S;
int needTime;
scanf("%d:%d:%d%d", &H, &M, &S, &needTime);
Person temp;
temp.arriveTime = H * 3600 + M * 60 + S;
temp.needTime = needTime;
person.push_back(temp);
}
}
//將等待佇列按到達時間排序
int compareArriveTime(Person &a, Person &b) {
return a.arriveTime < b.arriveTime;
}
//在銀行服務前將每個視窗排一人(每個視窗第一個辦理業務的人)
int fillQue(vector<Person> &person, vector<queue<Person>>&que) {
int ptr = 0;
for (int i = 0; i < que.size() && ptr < person.size(); i++) {
if (person[ptr].arriveTime <= 8 * 3600) { //如果8點以前到達則開始時間為8點
person[ptr].startTime = 8 * 3600;
}
else {
person[ptr].startTime = person[ptr].arriveTime; //如果8點以後到達則開始時間為到達時間
}
person[ptr].endTime = person[ptr].startTime + person[ptr].needTime * 60;
que[i].push(person[ptr++]);
}
return ptr;
}
//計算每個人的開始服務時間和結束時間
void enQue(vector<Person> &person, vector<queue<Person>>&que, int ptr) {
while (ptr < person.size()) {
int min = 0;
//找到最先結束的視窗
for (int i = 1; i < que.size(); i++) {
if (que[min].front().endTime > que[i].front().endTime) {
min = i;
}
}
if (person[ptr].arriveTime <= que[min].back().endTime)
person[ptr].startTime = que[min].back().endTime;
else
person[ptr].startTime = person[ptr].arriveTime;
person[ptr].endTime = person[ptr].startTime + person[ptr].needTime * 60;
que[min].pop();
que[min].push(person[ptr++]);
}
}
//計算總的等待時間
int allWaiteTime(vector<Person>&person, int &ptr) {
int allTime = 0;
while (person[ptr].arriveTime <= 17 * 3600 && ptr < person.size()) {
allTime += (person[ptr].startTime - person[ptr].arriveTime);
ptr++;
}
return allTime;
}
int main() {
vector<Person>person; //等待佇列
vector<queue<Person>>que;// 銀行視窗
input(person, que);
sort(person.begin(), person.end(), compareArriveTime);
int ptr = fillQue(person, que);
enQue(person, que, ptr);
ptr = 0;
int allTime = allWaiteTime(person, ptr);
//如果都17點以後到達的情況
if (ptr == 0) {
cout << "0.0" << endl;
}
else
printf("%.1lf\n", allTime / (60.0 * ptr));
}