PAT甲级1017解法

Posted aopstudio

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT甲级1017解法相关的知识,希望对你有一定的参考价值。

原题链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805491530579968

思路

这题也出现了时间,我们根据上一题的经验同样把时分秒转换为自零点零分零秒开始经过的秒数。这题也出现了窗口排队,之前也有题目可以参考,而且这次每个窗口最多排一个,更加简单。另外,之前用过的sort排序这里也有用处。本来我的想法是先填满所有窗口,将没排进窗口的统一放在一个队列中存储,但这个方法比较复杂,而且容易出错。参考了网上的一个方法,将17点之后到的在输入时就排除掉,而之前到的全部放在一个vector中,之后遍历vector,同时遍历查找每个窗口完成当前接待的最早时间,之后进行更新。

代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct record
{
    int time, process;  //time代表到达时间,为从00:00:00开始经过的秒数
};
bool compare(record a, record b)
{
    return a.time < b.time;
}
int main()
{
    const int EIGHT = 8 * 3600; //八点代表的秒数
    const int SEVENTEEN = 17 * 3600;    //十七点代表的秒数
    int N, K;
    double totalTime = 0.0; //所有顾客的等待时间
    cin >> N >> K;
    vector<record> records; //存储所有记录
    for (int i = 0; i < N; i++)
    {
        record newRecord;
        int hour, minute, second;
        scanf("%d:%d:%d %d", &hour, &minute, &second, &newRecord.process);
        newRecord.time = hour * 3600 + minute * 60 + second;
        if (newRecord.time > SEVENTEEN) //如果晚于17:00则不计入
            continue;
        newRecord.process *= 60;    //分钟转换为秒
        records.push_back(newRecord);   //添加新记录
    }
    sort(records.begin(), records.end(), compare);
    vector<int> linesTime(K, EIGHT);    //每个窗口完成当前接待的时间,初始化都为8点
    for (int i = 0; i < records.size(); i++)
    {
        int min = linesTime[0], index = 0;
        for (int i = 1; i < K; i++) //找出最早完成前一个处理的窗口
        {
            if (linesTime[i] < min)
            {
                min = linesTime[i];
                index = i;
            }
        }
        record r = records[i];
        if (linesTime[index] <= r.time) //来的时间晚于窗口完成前一个处理的时间
        {
            linesTime[index] = r.time + r.process;  //到达时间加处理时间为窗口完成当前处理的时间,等待时间为0,无需更新
        }
        else //来的时间早于窗口完成前一个处理的时间
        {
            totalTime += linesTime[index] - r.time; //等待时间加上窗口完成当前处理的时间减到达时间
            linesTime[index] += r.process;  //窗口完成当前处理的时间为完成前一个处理的时间加处理时间
        }
    }
    if (records.size() == 0)    //没有符合的条件,直接输出0.0,因为0不能作除数
        cout << 0.0;
    else
    {
        double average = totalTime / 60.0 / records.size(); //计算平均等待时间(单位为分钟)
        printf("%.1lf", average);
    }
    return 0;
}

以上是关于PAT甲级1017解法的主要内容,如果未能解决你的问题,请参考以下文章

PAT甲级1018解法

PAT 甲级 1017 Queueing at Bank

PAT 1017

PAT(甲级)2018年冬季考试 7-4 Heap Paths(非递归与递归解法)

PAT甲级排队问题合集 (持续更新中)

PAT甲级--Consecutive Factors