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
二、解题思路
这道题是一道大模拟题,解题步骤还是非常复杂的,我一开始是没有想到解法的,直接用了柳神的代码(这是种非常不好的行为)。在这里讲一下自己的理解吧。这篇文章不能算原创。基本模型是这样的:
首先,搞清楚每个变量的意义:
窗口数
一条队伍可以容纳的人数
总客户数
询问的客户编号
对于时间,我们最好全部转换成分钟,方便比较和计算。对于窗口,我们建立一个结构体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;
}