1014 Waiting in Line (30 point(s))
Suppose a bank has N windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. The rules for the customers to wait in line are:
- The space inside the yellow line in front of each window is enough to contain a line with M customers. Hence when all the N lines are full, all the customers after (and including) the (N x M + 1)st one will have to wait in a line behind the yellow line.
- Each customer will choose the shortest line to wait in when crossing the yellow line. If there are two or more lines with the same length, the customer will always choose the window with the smallest number.
- Customeri will take Ti minutes to have his/her transaction processed.
- The first N customers are assumed to be served at 8:00am.
Now given the processing time of each customer, you are supposed to tell the exact time at which a customer has his/her business done.
For example, suppose that a bank has 2 windows and each window may have 2 custmers waiting inside the yellow line. There are 5 customers waiting with transactions taking 1, 2, 6, 4 and 3 minutes, respectively. At 08:00 in the morning, customer1 is served at window1 while customer2 is served at window2. Customer3 will wait in front of window1 and customer4 will wait in front of window2. Customer5 will wait behind the yellow line.
At 08:01, customeri is done and customer5 enters the line in front of window1 since that line seems shorter now. Customer2 will leave at 08:02, customer4 at 08:06, customer3 at 08:07, and finally customer5 at 08:10.
Input Specification:
Each input file contains one test case. Each case starts with a line containing 4 positive integers: N (≤ 20, number of windows), M (≤ 10, the maximum capacity of each line inside the yellow line), K (≤ 1000, number of customers), and Q (≤ 1000, number of customer queries).
The next line contains K positive integers, which are the processing time of the K customers.
The last line contains Q positive integers, which represent the customers who are asking about the time they can have their transactions done. The customers are numbered from 1 to K.
Output Specification:
For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MM where HH is in [08, 17] and MM is in [00, 59]. Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output Sorry instead.
Sample Input:
2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7
Sample Output:
08:07
08:06
08:10
17:00
Sorry
题目大意:
银行 8:00am 开始工作,N 个窗口,每个窗口容纳 M 个人排队,K 名顾客,每名顾客对应一个处理业务所需的时间,Q 次查询;求每次查询的顾客的结束时间;顾客 17:00 及 17:00 以后还未开始服务的,不再提供服务输出 sorry
顾客入队规则如下:
- 顾客按输入顺序依次入队
- 当窗口未满时,按窗口号从小到大,队列长度最小,进入对应窗口排队;窗口满,黄线外等候
- 某一列结束一人,黄线外进一人;若同时多列结束,选择窗口号小的
设计思路:
转化为求顾客的入队时间,即可根据处理业务时间计算结束时间
- 结构体,每位顾客的入队时间 pushtime,处理业务时间 time
- 结构体,为每个窗口维护一个队列(入队过程中,此一维数组模拟循环队列,以防止数组越界,并节约空间),记录队首出队时间 poptime,队尾结束的时间 endtime
- 队列未满时,依次入队,入队过程中根据入队的顾客初始化队列
- 初始化队列,此队列
poptime = 第一位顾客的处理时间
,此队列结束时间endtime = 第一位顾客业务时间
- 继续入队列,此队列结束时间
endtime += 顾客业务时间累加
- 初始化队列,此队列
- 队列已满时,根据维护队列的 poptime,查询最先出队的顾客,此顾客出队列,黄线外下一顾客入队,出入队列过程更新此队列信息
- 出队列,此队列
poptime += 队列中第二位顾客的处理时间
- 入队列,此顾客的入队时间
pushtime = 此队列的 endtime
,此队列结束时间endtime += 此顾客业务时间
- 出队列,此队列
- 所有顾客入队完毕,其入队时间全部更新,即可查询
注:对 17:00 以前已经开始处理业务的顾客,不管处理到多晚,结束时间都如实输出,即 17:00 时银行不关门但不接受新业务;
1017 题不需要实际维护对应的队列,而本题需要,因为本题在队满出队时,必须要知道队列中第二位顾客的信息,才能更新此队列最新的出队时间,所以要维护完整的队列信息;
编译器:C (gcc)
#include <stdio.h>
struct window {
int poptime;
int endtime;
int queue[11];
int front, rear, length;
};
struct customer {
int time;
int pushtime;
};
int main(void)
{
int n, m, k, q;
struct window windows[21] = {0};
struct customer customers[1001] = {0};
int i, j;
scanf("%d %d %d %d", &n, &m, &k, &q);
int push = 0;
for (i = 1; i <= k; i++) {
scanf("%d",&customers[i].time);
if (i <= m * n) {
push = push % n;
push++;
} else {
push = 1;
for (j = 1; j <= n; j++) {
if (windows[j].poptime < windows[push].poptime)
push = j;
}
}
if (windows[push].length == 0)
windows[push].poptime = customers[i].time;
if (windows[push].length == m) {
windows[push].front++;windows[push].front %= 11;
windows[push].length--;
windows[push].poptime += customers[windows[push].queue[windows[push].front]].time;
}
customers[i].pushtime = windows[push].endtime;
windows[push].endtime += customers[i].time;
windows[push].queue[windows[push].rear] = i;
windows[push].rear++;windows[push].rear %= 11;
windows[push].length++;
}
for (i = 0; i < q; i++) {
int tmp, query;
scanf("%d", &query);
tmp = customers[query].pushtime + customers[query].time;
if (customers[query].pushtime >= (17 - 8) * 60)
printf("Sorry\n");
else
printf("%02d:%02d\n", tmp / 60 + 8, tmp % 60);
}
return 0;
}