PAT 甲级测试题目 -- 1014 Waiting in Line

题目链接

题目大意

银行有 N 个窗口,窗口前有一条黄线。并且有以下规则

  1. 黄线前每个窗口足够容纳 M 名顾客,因此若 N 个队伍都满了,则其余的乘客需要站在黄线外面等候
  2. 每名顾客都会选择最短的一队进入黄线区域(黄线内队伍中有顾客办理完成手续了),如果有两队人数一样,则从窗口号较小的队伍插入。
  3. 每名顾客都有自己办理业务的时间
  4. 业务办理从 8:00 开始,到 17:00 结束。

思路

两种情况:

  1. 黄线内的容量大于来办理业务的顾客。
      将黄线内的顾客办理业务的时间存起来,因为头一批到达黄线内的顾客按照从左到右的顺序进入队伍就好。因此计算出各自的时间即可。
    2.黄线内的容量小于来办理业务的顾客。
      将黄线内的顾客办理业务的时间存起来,并计算出每个窗口在黄线内顾客办理完业务后的时间,用于计算后面的顾客办理业务的时间。然后找出每个窗口队伍第一个人办理业务最短的时间,弹出这个元素,并计算当前最短的队伍,然后将 在黄线后面等待的顾客 插入到这个队伍中,并计算对应的时间即可。

坑点

  1. 要考虑黄线容纳顾客的情况,可能可以完全容纳,也可能容纳不下
  2. 考虑 17:00 这个时间点。原题中的描述:
    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.
    注意由于银行每天 17:00 之后下班,因此那些在 17:00 之前没有被服务到的顾客,你需要输出 Sorry。
  3. 注意处理 M 为 0 的情况

实现

#include <iostream>
#include <string.h>
#include <queue>
#include <map>

using namespace std;

int main() {
    int N, M, K, Q;
    int Time[1000]; // 存储每个顾客进店之后到办理结束后的时间,无法办理的值为 -1
    // int yellow[10][20]; // 存储黄线内第一行的窗口处理时间
    map<int, queue<int>> yellow;

    int wait_time; // 存储每次输入的顾客办理业务时间
    int sequence[1000], seq_index = 0; // 存储黄线之外顾客进入窗口的顺序
    int number = 0; // 存储进入顾客的编号
    int min_time = 999999, min_index = 0; // 存储最短办理时间 进入队列的顺序
    int windows_time[20]; // 记录每个窗口的时间,用于计算每个顾客办理业务的时间
    int min_length = 99999, min_len_index = 0; // 记录窗口前队伍的最短长度

    cin >> N >> M >> K >> Q;
    if (M == 0)
        M = 1;

    memset(windows_time, 0, sizeof(windows_time));
    memset(Time, 0, sizeof(Time));
    int circle = N*M < K ? N*M : K; // 处理办理业务的人数小于黄线内等待人数的情况

    // 存储黄线内顾客的等待时间
    for (int i = 0; i < circle; ++i) {
        cin >> wait_time;
        if (yellow.count(i % N) == 0) {
            queue<int> temp;
            temp.push(wait_time);
            yellow.insert(pair<int, queue<int>>(i % N, temp));
        } else {
            map<int, queue<int>>::iterator iter = yellow.find(i % N);
            iter->second.push(wait_time);
        }

        if (windows_time[i % N] >= 540)
            Time[number++] = -1;
        else {
            windows_time[i % N] += wait_time;
            Time[number++] = windows_time[i % N];
        }

    }

    // 计算所有顾客的等待时间
    for (int i = 0; i < K - N * M; ++i) {
        cin >> wait_time;
        for (map<int, queue<int>>::iterator iter = yellow.begin(); iter != yellow.end(); iter++) {
            if (min_time > iter->second.front()) {
                min_time = iter->second.front();
                min_index = iter->first;
            }
        }

        for (map<int, queue<int>>::iterator iter = yellow.begin(); iter != yellow.end(); iter++) {
            if (min_index == iter->first) {
                iter->second.pop();
            } else {
                iter->second.front() -= min_time;
            }

            if(min_length > iter->second.size()){
                min_length = iter->second.size();
                min_len_index = iter->first;
            }
        }

        yellow.find(min_len_index)->second.push(wait_time);

        if (windows_time[min_index] >= 540)
            Time[number++] = -1;
        else {
            windows_time[min_index] += wait_time;
            Time[number++] = windows_time[min_index];
        }


        min_length = min_time = 999999;
    }

    // 根据输入的序列输出时间

    for (int i = 0; i < Q; ++i) {
        int hour = 8, minutes = 0; // 定义时间,方便输出
        cin >> wait_time; // 这里不想定义额外的变量,就使用这个了
        minutes = Time[wait_time - 1];
        hour += (minutes / 60);
        minutes %= 60;
        if (Time[wait_time - 1] == -1) {
            cout << "Sorry";
        } else {
            if (hour < 10)
                cout << "0" << hour << ":";
            else
                cout << hour << ":";
            if (minutes < 10)
                cout << "0" << minutes;
            else
                cout << minutes;
        }
        if (i < Q - 1)
            cout << endl;
    }
}
上一篇:进程间的通信


下一篇:谈谈多线程