欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PAT甲级1014 Waiting in Line (30分)|C++实现

程序员文章站 2022-06-07 14:40:23
...

一、题目描述

PAT甲级1014 Waiting in Line (30分)|C++实现

Input Specification:

Each input file contains one test case. Each case starts with a line containing 4 positive integers: N (≤20, number of windows), M (≤10, the maximum capacity of each line inside the yellow line), K (≤1000, number of customers), and Q (≤1000, number of customer queries).

The next line contains K positive integers, which are the processing time of the K customers.

The last line contains Q positive integers, which represent the customers who are asking about the time they can have their transactions done. The customers are numbered from 1 to K.

​​Output Specification:

For each of the Q customers, print in one line the time at which his/her transaction is finished, in the format HH:MM where HH is in [08, 17] and MM is in [00, 59]. 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.

Sample Input:

2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7

Sample Output:

08:07
08:06
08:10
17:00
Sorry

二、解题思路

这道题是一道大模拟题,解题步骤还是非常复杂的,我一开始是没有想到解法的,直接用了柳神的代码(这是种非常不好的行为)。在这里讲一下自己的理解吧。这篇文章不能算原创。基本模型是这样的:
PAT甲级1014 Waiting in Line (30分)|C++实现
首先,搞清楚每个变量的意义:
N:N: 窗口数
M:M: 一条队伍可以容纳的人数
K:K: 总客户数
Q:Q: 询问的客户编号
对于时间,我们最好全部转换成分钟,方便比较和计算。对于窗口,我们建立一个结构体Window,里面要包括最早会有空位的时间poptime,以及最终的结束时间endtime。以及一个客户队列(注意这里储存的是客户用的时间而不是客户编号,因为没有必要用编号)。win[i]即表示第i个窗口。此外,我们还定义了两个vector<int>,一个是time,time[i]表示第i个客户需要的服务时间;另一个是result,result[i]表示第i个客户结束服务的时间(单位为分钟)。当然,我们还要判断后面的客户进队的时候会不会超时,这里定义一个vector<bool>,即sorry。

接下来我们正式开始解决这个问题。对于输入的事情就不多讲了。输入完之后,就要开始进行排队了,按照我们上面画的示意图,按客户顺序应该是从左往右一直排下来,直到客户在黄线内的区域排满。我们先讨论这个过程。建立一个二层循环,外层是从1到M,也即“行”,内层是从1到N,也即“列”。我们用index表示当前计算的客户。当客户的编号不大于K时,我们将对应的时间加入对应窗口的队列,同时要判断该窗口的endtime是否大于17:00,若大于,则该客户超时,sorry[index]设为true。随后,我们要更新该窗口的endtime和poptime。最后让index++。

接下来处理K大于M*N的情况。我们先将tempmin设置为第一个窗口队伍有空位的时间,即win[1].poptime。将tempwindow设为1。接着遍历所有窗口,找出poptime最小的那个,随后将这个窗口的客户队列进行pop操作并更新poptime。接着还要判断,这个窗口的endtime是否会大于17:00,如果大于,则sorry[index]要设为true,否则计算该客户的服务结束时间,即result[index]。随后更新endtime,index++。

最后就非常简单了,先判断sorry[query]是否为true,然后再输出result[query]。

三、AC代码

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxW = 22;
struct Window
{
  int poptime, endtime;
  queue<int> customer;
}win[maxW];
int main()
{
  int N, M, K, Q, index = 1;
  scanf("%d%d%d%d", &N, &M, &K, &Q);
  vector<int> time(K+1), result(K+1);
  for(int i=1; i<=K; i++)
  	scanf("%d", &time[i]);
  vector<bool> sorry(K+1, false);
  for(int i=1; i<=M; i++)
  {
    for(int j=1; j<=N; j++)
    {
      if(index <= K)
      {
        win[j].customer.push(time[index]);
        if(win[j].endtime >= 540)
          sorry[index] = true;
        win[j].endtime += time[index];
        if(i==1)
          win[j].poptime = win[j].endtime;
        result[index] = win[j].endtime;
        index++;
      }
    }
  }
  while(index <= K)
  {
    int tempmin = win[1].poptime, tempwindow = 1;
    for(int i=2; i<=N; i++)
    {
      if(win[i].poptime < tempmin)
      {
        tempwindow = i;
        tempmin = win[i].poptime;
      }
    }
    win[tempwindow].customer.pop();
    win[tempwindow].customer.push(time[index]);
    win[tempwindow].poptime += win[tempwindow].customer.front();
    if(win[tempwindow].endtime>=540)	sorry[index] = true;
    win[tempwindow].endtime += time[index];
    result[index] = win[tempwindow].endtime;
    index++;
  }
  for(int i=1; i<=Q; i++)
  {
    int query, minute;
    scanf("%d", &query);
    minute = result[query];
    if(sorry[query])	printf("Sorry\n");
    else printf("%02d:%02d\n", (minute+480)/60, (minute+480)%60);
  }
  return 0;
}
相关标签: PAT Advanced