题目大意:
银行有N个窗口,每个窗口前最多可以排M个人,现在又K位客户需要服务,每位客户服务的时常已知,假设所有的客户均在8:00按客户编号依次等待在黄线外,且如果又窗口的排队人数没有满(没有到达M人),当前在黄线外的第一个客户就会选择这样的窗口中排队人数最少的窗口去排队(排队人数相同,选择窗口序号较小的窗口去排队)。给出Q个查询,每个查询给出一位客户编号,输出这位客户的服务结束时间,如果一个客户在17:00之后还没有被服务,则不再服务,输出Sorry,而一个客户在17:00之前被服务,不论它的服务时长又多长,都会接受完整服务。
思路:
1.当一位客户进入某一窗口队列时,他的服务时间就已经确定了,即当前在该窗口排队的所有人的服务时间之和,而在所有窗口排满后,剩余客户能够去排队的时间点时所有窗口最找结束的队首客户,也就是说,在所有窗口排满的情况下,每当有一个窗口的队首客户结束服务,(结束时间相同,窗口ID小的视为先结束),剩余客户的第一个就会排到那个窗口的最后面。
可以建立一个窗口结构体window,存放当前队伍的最后服务时间endTime和队首客户的服务结束时间popTime,并维护一个该窗口排队的队列q。
2.在8:00前,只要窗口的队列没满,就把客户按照窗口编号0,1,2,…,n-1,0,1,2…n-1循环入队,且在安排的过程中不断的更新窗口的endTime和popTime,其中endTime将直接刚入队的客户的服务结束时间保存下来,而popTime尽在安排每个窗口的第一客户实时更新。
3.如果步骤2已经将所有的窗口都排满,那么在该步中将剩下的客户入队,由于所有的窗口排满的情况下,每当又一个窗口的队首客户结束服务(结束时间相同,ID小的视为先结束),剩余客户的第一个就会排到那个客户后面,对每一个这样的客户,可以选择当前所有窗口中popTime中最小的窗口,popTime相同选择ID较小的,将客户排到该窗口的队列后面,并更新该窗口的endTime和popTime,其中endTime作为刚入队的客户的服务结束时间保存。
4.对每一个输入的查询客户编号,如果他的服务开始时间在17:00之后(含17:00),则输出sorry,否则,输出他的服务结束时间。
5.把所有的时间转换为分钟,以便时间的处理与比较。
AC代码:
//PAT_A 1014
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 1111;
int convertTime(int hh, int mm) {
return hh * 60 + mm;
}
struct Window {
int endTime, popTime;//