PAT 1017

最近由于在刷PAT的甲级题目,开始花时间整理一下一些题目的思路,以下是这题银行排队题目的主要想法和AC源码

1017. Queueing at Bank (25)

Suppose a bank has K windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. All the customers have to wait in line behind the yellow line, until it is his/her turn to be served and there is a window available. It is assumed that no window can be occupied by a single customer for more than 1 hour.

Now given the arriving time T and the processing time P of each customer, you are supposed to tell the average waiting time of all the customers.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 numbers: N (<=10000) - the total number of customers, and K (<=100) - the number of windows. Then N lines follow, each contains 2 times: HH:MM:SS - the arriving time, and P - the processing time in minutes of a customer. Here HH is in the range [00, 23], MM and SS are both in [00, 59]. It is assumed that no two customers arrives at the same time.

Notice that the bank opens from 08:00 to 17:00. Anyone arrives early will have to wait in line till 08:00, and anyone comes too late (at or after 17:00:01) will not be served nor counted into the average.

Output Specification:

For each test case, print in one line the average waiting time of all the customers, in minutes and accurate up to 1 decimal place.

Sample Input:

7 3
07:55:00 16
17:00:01 2
07:59:59 15
08:01:00 60
08:00:00 30
08:00:02 2
08:03:00 10

Sample Output:

8.2

这题属于典型的模拟题,对每个8:00到17:00中间来的用户都会进行服务,也就是,即使你16:59分到,发现前面的用户服务时间需要到17:05,只要17:00前到了,也会被服务

客户来的时间是乱序的,因此我使用优先队列维护客户来的时间,采用小根堆,需要重写一个比较函数operator > ,因为priority_queue是默认大根的,这里要小心  关于优先队列的使用有两种需要注意,  一种是内置类型,可以使用greater<int> less<int> 构造:
    priority_queue<int, vector<int>, greater<int> > q; //自定义大小函数
    int n;
    cin >> n;
    while(n--)
    {
        int a;
        cin >> a;
        q.push(a);
    }

    while(!q.empty())
    {
        cout << q.top() << endl;
        q.pop();
    }
    return 0;

  第二种自定义类型, struct或者是class

struct Student
{
public:
    int grade;
    int name;
};

class cmp
{
public:
    bool operator() (const Student &s1, const Student &s2) //必须重写operator函数,public的
    {
        return s1.grade < s2.grade; //注意,此处定义的大小符号
    }
};
int main()
{
    priority_queue<int, vector<Student>, cmp > q;

    int n;
    cin >> n;
    while(n--)
    {
        Student s;
        cin >> s.grade;
        cin >> s.name;
        q.push(s);
    }

    while(!q.empty())
    {
        cout << q.top().grade << endl;
        q.pop();
    }
    return 0;
}
进入正题:
#include <iostream>
#include <stdio.h>
#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std;

class Bank
{
public:
  int h;
  int m;
  int s;
  int time;

public:  //计算秒值,作为排序依据
  int value() const
  {
    return h * 3600 + m * 60 + s;
  }

  bool operator < (Bank b) const
  {
     return value() > b.value();
  }
};

int main()
{
    int N,K;
    int que[101];
    for(int i = 0; i < 101; i ++)
    {
        que[i] = 8 * 3600;
    }
    int early = 0; //early记录当前最早结束的是哪个队列

    priority_queue<Bank> q;

    scanf("%d", &N);
    scanf("%d", &K);

    while(N--)
    {
        Bank bank;
        if(bank.time > 60)
            bank.time = 60;
        scanf("%d:%d:%d", &bank.h, &bank.m, &bank.s);
        scanf("%d", &bank.time);
        q.push(bank);
    }

    int n = 0;
    long wait = 0;
    while(!q.empty())
    {
        Bank b = q.top();
        q.pop();        //如果是八点前来的 
        if(b.value() < 8 * 3600)
        {            //必须等待
            wait += que[early] - b.value();
            que[early] += b.time * 60;
            int min = 0x3f3f3f3f;
            int index = 0;       //刷新最快结束的队列
            for(int i = 0; i < K; i++)
            {
               if( que[i] < min )
               {
                   index = i;
                   min = que[i];
               }
            }
            early = index;
        }
        else if(b.value() > 17 * 3600)
        {//5点后来的不服务
            break;
        }
        else
        {  //如果到的时候没有空闲的队伍,等待
            if(que[early] > b.value())
            {
                wait += que[early] - b.value();
                que[early] += b.time * 60;
            }
            else
            { 
                que[early] = b.value() + b.time * 60;
            }
            int min = 0x3f3f3f3f;
            int index = 0;
            for(int i = 0; i < K; i++)
            {
               if( que[i] < min )
               {
                   min = que[i];
                   index = i;
               }
            }
            early = index;
        }

        n ++;
    }
    if( n == 0 )
    {
        printf("0.0\n");
        return 0;
    }
    printf("%.1f", double((int((double)wait/n/60 * 10+ 0.5)))/10);

    return 0;
}

				
时间: 2024-10-19 20:23:21

PAT 1017的相关文章

PAT 1017 Queueing at Bank[一般]

1017 Queueing at Bank (25)(25 分)提问 Suppose a bank has K windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. All the customers have to wait in line behind the yellow line, until it is

PAT 1017. Queueing at Bank

又是排队模拟 #include <iostream> #include <cstdlib> #include <vector> #include <list> #include <queue> using namespace std; class Man { public: int arrive; int need; int start; Man(int a, int n) : arrive(a), need(n), start(0) {} };

PAT 1017. A除以B (20)

本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数.你需要输出商数Q和余数R,使得A = B * Q + R成立. 输入格式: 输入在1行中依次给出A和B,中间以1空格分隔. 输出格式: 在1行中依次输出Q和R,中间以1空格分隔. 输入样例: 123456789050987654321 7 输出样例: 17636684150141093474 3 这道题找了老半天的错,在本机调试多个答案都正确,但提交后却都不对,最后发现是temp没有赋初值0.以后得多加注意 1 #includ

PAT 1017 Queueing at Bank (25) (坑题)

Suppose a bank has K windows open for service. There is a yellow line in front of the windows which devides the waiting area into two parts. All the customers have to wait in line behind the yellow line, until it is his/her turn to be served and ther

PAT 1017 A除以B

https://pintia.cn/problem-sets/994805260223102976/problems/994805305181847552 本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数.你需要输出商数Q和余数R,使得A = B * Q + R成立. 输入格式: 输入在1行中依次给出A和B,中间以1空格分隔. 输出格式: 在1行中依次输出Q和R,中间以1空格分隔. 输入样例: 123456789050987654321 7 输出样例: 17636684150

PAT 乙级 1017

题目 题目地址:PAT 乙级 1017 题解 粗看是一道大数除法题,实际上只不过是通过字符数组模拟除法过程,理解之后还是比较简单的: 具体分析一下本题: 因为题设中的除数(n)是一位整数,因此大幅简化了整个运算过程:在整个运算中最为重要的就是中间变量(sum),判断中间变量sum是否足够大能被除数n整除,这也是本题的关键所在: 通过是否判断sum是否能被整除,可以分为以下两种情况: 1. sum == 0 && num[i] < n (当前运算位num[i]小于除数) 2. 其余情况

PAT乙级 1017. A除以B (20)

1017. A除以B (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数.你需要输出商数Q和余数R,使得A = B * Q + R成立. 输入格式: 输入在1行中依次给出A和B,中间以1空格分隔. 输出格式: 在1行中依次输出Q和R,中间以1空格分隔. 输入样例: 123456789050987654321 7 输出样例: 176366

PAT 乙级 1017 A除以B (20) C++版

1017. A除以B (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数.你需要输出商数Q和余数R,使得A = B * Q + R成立. 输入格式: 输入在1行中依次给出A和B,中间以1空格分隔. 输出格式: 在1行中依次输出Q和R,中间以1空格分隔. 输入样例: 123456789050987654321 7 输出样例: 176366

PAT乙级1017

1017 A除以B (20分) 题目地址:https://pintia.cn/problem-sets/994805260223102976/problems/994805305181847552 本题要求计算 A/B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数.你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立. 输入格式: 输入在一行中依次给出 A 和 B,中间以 1 空格分隔. 输出格式: 在一行中依次输出 Q 和 R,中间以 1 空格分隔. 输入样例 1234