最近由于在刷PAT的甲级题目,开始花时间整理一下一些题目的思路,以下是这题银行排队题目的主要想法和AC源码
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 (<=10000) - 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 这题属于典型的模拟题,对每个8:00到17:00中间来的用户都会进行服务,也就是,即使你16:59分到,发现前面的用户服务时间需要到17:05,只要17:00前到了,也会被服务 客户来的时间是乱序的,因此我使用优先队列维护客户来的时间,采用小根堆,需要重写一个比较函数operator > ,因为priority_queue是默认大根的,这里要小心 关于优先队列的使用有两种需要注意, 一种是内置类型,可以使用greater<int> less<int> 构造:
priority_queue<int, vector<int>, greater<int> > q; //自定义大小函数 int n; cin >> n; while(n--) { int a; cin >> a; q.push(a); } while(!q.empty()) { cout << q.top() << endl; q.pop(); } return 0;
第二种自定义类型, struct或者是class
struct Student { public: int grade; int name; }; class cmp { public: bool operator() (const Student &s1, const Student &s2) //必须重写operator函数,public的 { return s1.grade < s2.grade; //注意,此处定义的大小符号 } }; int main() { priority_queue<int, vector<Student>, cmp > q; int n; cin >> n; while(n--) { Student s; cin >> s.grade; cin >> s.name; q.push(s); } while(!q.empty()) { cout << q.top().grade << endl; q.pop(); } return 0; }
进入正题:
#include <iostream> #include <stdio.h> #include <queue> #include <stdio.h> #include <string.h> using namespace std; class Bank { public: int h; int m; int s; int time; public: //计算秒值,作为排序依据 int value() const { return h * 3600 + m * 60 + s; } bool operator < (Bank b) const { return value() > b.value(); } }; int main() { int N,K; int que[101]; for(int i = 0; i < 101; i ++) { que[i] = 8 * 3600; } int early = 0; //early记录当前最早结束的是哪个队列 priority_queue<Bank> q; scanf("%d", &N); scanf("%d", &K); while(N--) { Bank bank; if(bank.time > 60) bank.time = 60; scanf("%d:%d:%d", &bank.h, &bank.m, &bank.s); scanf("%d", &bank.time); q.push(bank); } int n = 0; long wait = 0; while(!q.empty()) { Bank b = q.top(); q.pop(); //如果是八点前来的 if(b.value() < 8 * 3600) { //必须等待 wait += que[early] - b.value(); que[early] += b.time * 60; int min = 0x3f3f3f3f; int index = 0; //刷新最快结束的队列 for(int i = 0; i < K; i++) { if( que[i] < min ) { index = i; min = que[i]; } } early = index; } else if(b.value() > 17 * 3600) {//5点后来的不服务 break; } else { //如果到的时候没有空闲的队伍,等待 if(que[early] > b.value()) { wait += que[early] - b.value(); que[early] += b.time * 60; } else { que[early] = b.value() + b.time * 60; } int min = 0x3f3f3f3f; int index = 0; for(int i = 0; i < K; i++) { if( que[i] < min ) { min = que[i]; index = i; } } early = index; } n ++; } if( n == 0 ) { printf("0.0\n"); return 0; } printf("%.1f", double((int((double)wait/n/60 * 10+ 0.5)))/10); return 0; }