PAT Advanced 1014. Waiting in Li

2019-02-08  本文已影响0人  OliverLew

我的PAT系列文章更新重心已移至Github,欢迎来看PAT题解的小伙伴请到Github Pages浏览最新内容。此处文章目前已更新至与Github Pages同步。欢迎star我的repo

题目

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:

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, customer_1 is served at window_1 while customer_2 is served at
window_2 . Customer_3 will wait in front of window_1 and customer_4
will wait in front of window_2 . Customer_5 will wait behind the yellow
line.

At 08:01, customer_1 is done and customer_5 enters the line in front of
window_1 since that line seems shorter now. Customer_2 will leave at
08:02, customer_4 at 08:06, customer_3 at 08:07, and finally customer_5
at 08:10.

Input Specification:

Each input file contains one test case. Each case starts with a line
containing 4 positive integers: N ( \le 20 , number of windows), M (
\le 10 , the maximum capacity of each line inside the yellow line), K (
\le 1000 , number of customers), and Q ( \le 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

思路

题意解读:

银行有N个窗口, 每个窗口允许排M个顾客. 一大早8点所有顾客商量好蜂拥而入,
那么情况有两种: 1, 顾客全部能排在队伍里; 2, 顾客人数太多, 有人排在外面,
要等前面的顾客完成离开, 再进入列列.

注意点:

代码结构

解读题目时提到可以存在两种情况, 我将这两种情况合并了一下:

总结这两种情况, 都是前K次是入列, 后K次是出列, 只需再计算出总的操作次数(出入记为
一次)即可, 其实就是max(2*K, M*N+K).

这样代码结构就是

循环max(2*K, M*N+K)次:
    如果是后K次:
        出列
    如果是前K次:
        入列

计时方法

数据结构:

操作主要在入列时(因为入列时间很重要)

入列时:

出列时:

代码

最新代码@github,欢迎交流

#include <stdio.h>

#define LATE_FLAG -1
#define FORWARD(I) ((I) = ((I) == 10) ? 0 : ((I) + 1))
#define TIME_FRONT(I) time[queue[I][front[I]]]
#define TIME_REAR_PREVIOUS(I) time[queue[I][rear[I] == 0 ? 10 : (rear[I] - 1)]]

int main()
{
    int N, M, K, Q, query;
    int time[1000], queue[20][11] = {{0}};
    int front[20] = {0}, rear[20] = {0}, length[20] = {0};

    scanf("%d %d %d %d", &N, &M, &K, &Q);
    for(int i = 1; i <= K; i++)
        scanf("%d", time + i);

    /* Total number of operations */
    int count = (K < M * N) ? (2 * K) : (K + M * N);
    /* Doing dequeues and enqueues for every customer */
    for(int i = 1; i <= count; i++)
    {
        if(i > count - K)      /* Dequeue in the last K operations */
        {
            /* Find the next customer */
            int time_span = 9999, next = -1;
            for(int j = 0; j < N; j++) if(length[j])
            {
                if(TIME_FRONT(j) < time_span)
                    next = j, time_span = TIME_FRONT(j);
                else if(next == -1 && TIME_FRONT(j) == LATE_FLAG)
                    next = j;
            }
            /* Dequeue */
            FORWARD(front[next]);
            length[next]--;
        }
        if(i <= K)               /* Enqueue in the first K operations */
        {
            /* Find shortest queue */
            int shortest = 0;
            for(int j = 0; j < N; j++)
                if(length[shortest] > length[j])
                    shortest = j;
            /* Set flag or add time */
            int previous_time = TIME_REAR_PREVIOUS(shortest);
            if(previous_time >= 9 * 60 || previous_time == LATE_FLAG)
                time[i] = LATE_FLAG;
            else
                time[i] += previous_time;
            /* Enqueue */
            queue[shortest][rear[shortest]] = i;
            FORWARD(rear[shortest]);
            length[shortest]++;
        }
    }

    /* Read queries and print answers */
    for(int i = 0; i < Q; i++)
    {
        scanf("%d", &query);
        if(time[query] != LATE_FLAG)
            printf("%02d:%02d\n", 8 + time[query] / 60, time[query] % 60);
        else
            printf("Sorry\n");
    }

    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读