PAT 甲级测试题目 -- 1017 Queueing at Bank

题目链接

题目概要

 银行有 N 个顾客和 K 个窗口。来办理业务的顾客必须等待在黄线之后,直到 8:00 开始办理业务。给出顾客到达银行的时间 HH:MM:SS(HH 的范围是[00, 23], MM 和 SS 的范围均为 [00, 59]),以及办理业务需要的时间 P(单位是分钟)。17:00 之后到店的顾客不予以服务。

分析

 有了 1016 题柳神对于时间处理的经验,使得我能更好的处理这道题的细节问题。但是要注意下述几个问题:

  1. 顾客数量为 0 时,由于计算平均时间需要 顾客数量 为分母,因此顾客数量为 0 直接输出 0.0就好了。
  2. 黄线是否能容纳下所有光临的顾客
    注意了上述问题之后,我的思路是:
  3. 初始化窗口办理完成的时间为 8:00。到店时间小于这个值的顾客,其差值为该顾客的等待时间,大于则直接办理,没有等待时间,当窗口办理完成的时间更新之后思路也是一样的。
  4. 之后在迭代的过程中,找出“初始化窗口办理完成的时间”的最小值,将后续的顾客加入进去,同时计算等待时间

实现

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct node {
    int hour, minutes, second, processTime, time;
};

bool cmp1(node a, node b) {
    return a.time < b.time;
}

bool cmp2(int a, int b) {
    return a < b;
}

int main() {
    int N, K; // 顾客数量 窗口数量
    cin >> N >> K;

    // 处理顾客为 0 的情况
    if (N == 0) {
        printf("%.1f", 0.0);
        return 0;
    }
    // 初始化 各个窗口的营业时间为 8:00
    int windows[100];
    for (int i = 0; i < K; ++i) {
        windows[i] = 8 * 60 * 60;
    }

    vector<node> customers;
    int giveup = 0;
    for (int i = 0; i < N; ++i) {
        node temp;
        scanf("%02d:%02d:%02d %d", &temp.hour, &temp.minutes, &temp.second, &temp.processTime);
        temp.time = temp.hour * 60 * 60 + temp.minutes * 60 + temp.second;
        // 处理 17:00 之后进来的顾客
        if (temp.time >= 17 * 3600) {
            giveup++;
        }
        customers.push_back(temp);
    }
    // 丢弃这些顾客
    N -= giveup;

    sort(customers.begin(), customers.end(), cmp1);

    double total = 0; // 总共的等待时间

    // 处理顾客
    for (int i = 0; i < N; ++i) {
        vector<node>::iterator iter = customers.begin();
        sort(windows, windows + K, cmp2);
        if (windows[0] > iter->time) {
            total += windows[0] - iter->time;
            windows[0] += iter->processTime * 60;
            customers.erase(iter);
        } else {
            windows[0] = iter->time + iter->processTime * 60;
            customers.erase(iter);
        }
    }

    // 输出答案
    printf("%.1f", total / (double) N / 60.0);
    return 0;
}

一次就 AC 了还是比较开心的
希望能帮到大家!

posted @ 2019-02-02 14:22  Intro1997  阅读(219)  评论(0编辑  收藏  举报