1026 Table Tennis (30分)
A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For any pair of players, if there are some tables open when they arrive, they will be assigned to the available table with the smallest number. If all the tables are occupied, they will have to wait in a queue. It is assumed that every pair of players can play for at most 2 hours.
Your job is to count for everyone in queue their waiting time, and for each table the number of players it has served for the day.
One thing that makes this procedure a bit complicated is that the club reserves some tables for their VIP members. When a VIP table is open, the first VIP pair in the queue will have the privilege to take it. However, if there is no VIP in the queue, the next pair of players can take it. On the other hand, if when it is the turn of a VIP pair, yet no VIP table is available, they can be assigned as any ordinary players.
Input Specification:
Each input file contains one test case. For each case, the first line contains an integer N (≤10000) - the total number of pairs of players. Then N lines follow, each contains 2 times and a VIP tag: HH:MM:SS - the arriving time, P - the playing time in minutes of a pair of players, and tag - which is 1 if they hold a VIP card, or 0 if not. It is guaranteed that the arriving time is between 08:00:00 and 21:00:00 while the club is open. It is assumed that no two customers arrives at the same time. Following the players’ info, there are 2 positive integers: K (≤100) - the number of tables, and M (< K) - the number of VIP tables. The last line contains M table numbers.
Output Specification:
For each test case, first print the arriving time, serving time and the waiting time for each pair of players in the format shown by the sample. Then print in a line the number of players served by each table. Notice that the output must be listed in chronological order of the serving time. The waiting time must be rounded up to an integer minute(s). If one cannot get a table before the closing time, their information must NOT be printed.
Sample Input:
9
20:52:00 10 0
08:00:00 20 0
08:02:00 30 0
20:51:00 10 0
08:10:00 5 0
08:12:00 10 1
20:50:00 10 0
08:01:30 15 1
20:53:00 10 1
3 1
2
Sample Output:
08:00:00 08:00:00 0
08:01:30 08:01:30 0
08:02:00 08:02:00 0
08:12:00 08:16:30 5
08:10:00 08:20:00 10
20:50:00 20:50:00 0
20:51:00 20:51:00 0
20:52:00 20:52:00 0
3 3 2
这真的是我目前为止做过最坑的一道题,无数个坑,我的心态和逻辑无数次崩塌。
本来以为和银行排队那两个题差不多,我还窃喜呢,结果,没想到加了个VIP能搞到那么复杂。
总体思路就是:
- 输入的时候如果顾客的用餐时间在两小时以上,压缩到两小时。
- 将所有顾客按照先来后到的顺序排序。
- 如果第一个顾客到达时间在打烊之前,给他安排一个桌子坐下。
3.1 如果他是VIP顾客,且有VIP桌子,给他安排号数最小的VIP桌子;
3.2 如果他是VIP顾客但没有VIP桌子,或他不是VIP顾客,给他安排号数最小的桌子。 - 如果第一个顾客到达时间就在打烊之后,直接结束。
- 寻找最先空出来的桌子。
5.1 如果这张桌子本来就是空的,它空出来的时间就是桌子当前时间。
5.2 如果这张桌子当前有人,它空出来的时间就是当前顾客吃完的时间。 - 如果找到的这张最先空出来的桌子本身是有人的,
6.1 如果当前的这个顾客开始接受服务的时间在打烊之前,将该顾客加入结果数组并记录其开始接受服务的时间。
6.2 更新桌子时间并把桌子清空。 - 如果后面还有人,给他安排位置,并跳到5继续循环,直到所有桌子全空了。
7.1 如果即将接受服务的这个人的到达时间在打烊之后,则把当前还在吃的桌子全部清空,并按照6.1的思路更新相关数据后结束。
7.2 如果即将接受服务的这个人已经接受过服务了,那就判断下一个。
7.3 如果即将接受服务的这个人到达时间比找到的这个桌子的时间晚,
7.3.1 如果这个桌子是VIP桌子,不管这个人是不是VIP,都直接上桌。
(因为他来的时候这个桌子已经空了,就算他不是VIP且后面有VIP,VIP来的时间也肯定比他晚,
也就是说他来的时候VIP还没来,不可能说放着空桌子不让坐)
7.3.2 如果这个桌子不是VIP桌子,这个人也不是VIP,那就直接坐。
7.3.3 如果这个桌子不是VIP桌子,但这个人是VIP,找他来的时候号数最小的空的VIP桌子,没有的话就还是坐这个桌子。
7.4 如果即将接受服务的这个人到达时间比找到的这个桌子的时间早,
7.4.1 如果这个桌子是VIP桌子,这个人也是VIP的话,直接坐。
7.4.2 如果这个桌子是VIP桌子,但这个人不是VIP的话,找后面第一个VIP,如果VIP到达时间比这个桌子时间早或等,就让VIP坐。否则还是给这个人。
7.4.3 如果这个桌子不是VIP桌子,不管这个人是不是VIP都直接坐。 - 如果后面没人了,把当前还在吃的桌子全部清空,并按照6.1的思路更新相关数据。
- 输出相关数据。
几个注意点:
- 用餐超过2小时要压缩为2小时。
- 21点及其之后到的人不能接受服务。
- VIP用户到的时候如果有VIP桌子空着,用编号最小的VIP桌子。
- 等待的时间要四舍五入。
卡住的几个测试点:
- 测试点3:可能出现运行时错误或运行超时。
这个测试点就是测的到达时间在21点及其之后是不能接受服务的这点。
样例输入:
2
20:00:00 10 0
21:00:00 10 0
3 1
2
样例输出:
20:00:00 20:00:00 0
1 0 0
- 测试点5:
VIP来的时候,如果有多个VIP桌子空出来,选择VIP桌号最小的而不是普通桌号最小的。
样例输入:
4
06:00:00 30 1
08:00:00 30 1
10:00:00 30 1
12:00:00 30 1
5 1
3
样例输出:
06:00:00 08:00:00 120
08:00:00 08:00:00 0
10:00:00 10:00:00 0
12:00:00 12:00:00 0
1 0 3 0 0
- 测试点7和8:
样例输入:
3
07:59:31 60 1
07:59:29 60 1
08:00:30 100 1
2 1
1
样例输出:
1
07:59:29 08:00:00 1
07:59:31 08: