PAT 1014 Waiting in Line (30分)

题目链接:点击这里

题意:假设一家银行有 N N N 个窗口在提供服务。窗口前有一条黄线,将等候区分成两部分。顾客排队的规则是:

  • 每个窗口前面的黄线内的空间足够容纳 M M M 个客户。因此,当所有的 N N N 个队伍都满了时,所有在 ( N ∗ M + 1 ) (N*M+1) (NM+1) 之后(包括)的客户将不得不在黄线后面排队等候。

  • 过黄线时,每位顾客都会选择最短的队伍等候。如果有两个或两个以上长度相同的窗口,客户总是会选择窗口编号更小的窗口。

  • 客户 i i i 将花费 T i T_i Ti 的时间处理他/她的事务。

  • 假定第一批顾客的服务时间是上午 8 点。

现在,给定每个客户的处理时间,您应该知道客户完成其业务的确切时间。

:如果一个客户的业务结束时间超过 17:00,这并不代表其无法完成服务。只要他在 17:00 前开始被服务,银行就必须给他服务完才能下班。

比如,有一个客户在 16:58 时才开始接受服务,哪怕他的业务办理时长为 60 60 60 分钟,银行也要给他办理完才能下班,这也与现实生活相符。所以,我们要看的是开始服务时间是否超过 17:00,而不是结束时间!

思路 N N N 个窗口用 N N N 个队列进行维护,记录每个顾客的开始服务时间、结束服务时间、业务办理时长,最后判断开始时间是否超过了 17 : 00 17:00 17:00,按要求输出即可。

注意:hh:mm 时间都转化为分钟,即 8:00 是 0 0 0,8:01 是 1 1 1,…,17:00 是 540 540 540

AC代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>

using namespace std;

struct node
{
    
    
    int cost, start, end;
}a[1010];

queue<node> q[25];

int main()
{
    
    
    // N个窗口,编号为1~N
    // 每个窗口最多排M个人
    // K个客户,编号为1~K
    // Q个询问
    int N, M, K, Q;
    scanf("%d%d%d%d", &N, &M, &K, &Q);
    
    for(int i = 1; i <= K; ++i) scanf("%d", &a[i].cost);
    
    for(int i = 1; i <= K; ++i)
    {
    
    
        if(i <= N * M)      // 初始,前N*M个人直接进黄线排队
        {
    
    
            int wid = (i - 1) % N + 1;              // 排到wid号窗口后面
            
            if(i <= N)  a[i].start = 0;             // 前N个人开始时间为0
            else    a[i].start = q[wid].back().end; // 否则,开始时间是上一个人的结束时间
            
            a[i].end = a[i].start + a[i].cost;
            q[wid].push(a[i]);
        }
        else
        {
    
    
            int wid = 1;
            for(int j = 2; j <= N; ++j)
            {
    
    
                if(q[j].front().end < q[wid].front().end)
                    wid = j;
            }
            
            q[wid].pop();
            
            // 当前此人排到wid号窗口后面
            a[i].start = q[wid].back().end;
            a[i].end = a[i].start + a[i].cost;
            q[wid].push(a[i]);
        }
    }
    
    while(Q--)
    {
    
    
        int id;
        scanf("%d", &id);
        
        // 如果开始服务时间超过了银行关门时间,则无法服务
        if(a[id].start >= 540)  puts("Sorry");
        else    printf("%02d:%02d\n", a[id].end / 60 + 8, a[id].end % 60);
    }

    return 0;
}

微信公众号《算法竞赛求职》,致力于详细讲解竞赛和求职所涉及到的算法原理和模板。欢迎关注,一起交流进步!

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/109145190