PAT 1014 Waiting in Line (30 分)

本文解析了一道PAT甲级题目,涉及排队论在银行窗口服务场景的应用。通过维护N个队列模拟窗口服务过程,解决客户咨询完成服务时间的问题,注意特殊情况如下班时间处理。C++代码展示了如何处理每分钟状态并判断是否超过17:00。
摘要由CSDN通过智能技术生成

1014 Waiting in Line (30 分)

今天给大家分享一道PAT甲级的小题,考察点:排队论

原题请点击我

简单翻译:

银行有N个窗口,每个窗口前可以站M个人,一共有K个人,他们最初按照1 - K的编号排队,起初所有人在黄线后面等待,如果某个窗口有空缺,等待的人就会顶上去,如果同一时间有很多空缺的,按照窗口编号的顺序顶上去。窗口为第 i 个人服务time[i]分钟。

问:这里有一串请求,表示第 j 个人在询问自己完成服务的时间是多少。如果完成完成时间在17:00以内,就输出这个时间,如果超过了17:00,就给客户输出Sorry。

思路:

简单的排队论,因为时间的范围并不是很大,从8:00-17:00只有540分钟,所以这里可以对每一分钟进行遍历。遍历的同时维护N个队列的状态。最终输出结果。

具体来说

我们申请N个队列,每个队列的容量是M,起初先把K个人往队列里面填,可能可以填满,可能填不满。接着以分钟为基本单位处理每个分钟下的状态即可。

小坑

按照常理来说,银行是17:00下班,但是如果银行在16:59开始处理你的事务,需要处理10分钟,他不会说还有1分钟就下班了,你明天再来吧这种话吧。所以如果再下班前已经开始处理某个人的信息的时候,这个人的信息是要处理完的。所以是有可能输出比17:00更大的数据的。注意到这一点,这个题就没有什么坑了。

C++ 代码:

#include"bits/stdc++.h"
#define all(x) x.begin(),x.end()
#define len(x) x.size()
#define INF (1e9)
#define vi vector<int>
#define ll long long int
#define ull unsigned long long int
#define db double
#define vvi vector<vector<int>>
#define pb(x) push_back(x);
using namespace std;
void f(int i) {
    int H = i / 60;
    int min = i % 60;
    printf("%02d:%02d\n", 8 + H, min);
}
int main() {
    int N, M, K, Q;
    cin >> N >> M >> K >> Q;
    vi time(K);
    for (int i = 0; i < K; i++) {
        cin >> time[i];
    }
    //pair.first 表示这是第几个人,pair.second表示这个人还需要成立多长时间
    vector<queue<pair<int, int>>> q(N, queue<pair<int, int>>());
    //t表示还没有入队的第一个人
    int t = 0;
    for (int i = 0; i < min(N * M, K); i++) {
        q[(t) % N].push(make_pair(t + 1, time[t]));
        t++;
    }
    vi quire(Q);
    for (int i = 0; i < Q; i++) {
        cin >> quire[i];
    }
    vi s(K, 0);
    //从8:00-17:00只有540分钟
    for (int i = 1; i <= 540; i++) {
        for (int j = 0; j < N; j++) {
            if (len(q[j]) != 0) {
                q[j].front().second--;
                if (q[j].front().second == 0) {
                    s[q[j].front().first] = i;
                    q[j].pop();
                    if (t < K) {
                        q[j].push(make_pair(t + 1, time[t]));
                        t++;
                    }
                }
            }
        }
    }
    //处理那些已经下班了,还没处理完的用户,要加班给人家处理一下
    for (int i = 0; i < N; i++) {
        if (len(q[i]) != 0) {
            if (time[q[i].front().first - 1] != q[i].front().second) {
                s[q[i].front().first] = 540 + q[i].front().second;
            }
        }
    }
    for (int i = 0; i < Q; i++) {
        if (s[quire[i]] != 0) {
            f(s[quire[i]]);
        } else {
            cout << "Sorry" << endl;
        }
    }
    return 0;
}

点我看PAT甲级全部题解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值