PAT(Advanced Level)1014——模拟题又一次题面挖坑
作者:互联网
一眼模拟,顾客蜂拥而至不需要考虑到达时间,无脑排队不会插队,因此不需要对服务时间进行排序之类的操作,问题已经非常简化过于友好了
proc[K]:每个人需要的业务服务时间
ret[K]:每个人业务服务进度(剩余时间)
wait[K]:每个人的等待时间
a[N][K]:N个队列的状态(从8:00开始)
cur[N]:N个队列正在服务的顾客(1~cur[i]-1是第i个队列已经服务过的顾客)
思路很简单,开门之前先把黄线以内的位置都安排好
每次都有一个业务服务时间剩余最少的人即将离开
我们只需要从每一列的当前服务对象中,找到这个 " 最快 " 的人即可
" 最快 " 的人完成业务后,就会离开银行
这时黄线后的第一个人就可以进入原先 " 最快 " 的人所在的那个队列继续等待
在 " 最快 " 的人完成业务时,所有队列的当前客户的业务服务进度都需要 " 前进 ",之后就重复寻找 " 最快 " 的人,让黄线外的人进入黄线
直到所有人都进入黄线在窗口前排队
那么每个人的等待时间如何计算?
想象一下当你在任何一个地方排队的时候
等待的时间只和你选择了排哪个队有关系
每当一个 " 最快 " 的人完成业务,所有人的时间都会推移,这一点其实已经体现在每个窗口当前客户的业务服务进度中
换句话说,每个人等待的时间就是
所在窗口 — 排在ta前面的所有人 — 业务服务时间之和
这就可以解释我们为什么要用a[N][K]把在第i个窗口排过队的人都记录下来
最后的输出= 排在前面的人的业务服务时间之和+自己的业务服务时间
最后一个阻碍你AC的绊脚石,就是PAT祖传的模糊描述了
刁钻测试点,都是一些题面挖的坑
测试点2和5:一个人如果开始时间在540之前(不包括540)即使结束时间超过540,依旧要服务
感谢浙大OIer提供测试数据情况
有兴趣的可以去看看其他佬的解决方案,都不错
给柳神引流了OOOooorz
Tip
数据范围看错了所有被干翻了四个点
一共就七个点,还是太着急了
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int N = 1000;
const int INF = 1e9;
int K, Q, n, m;
int proc[N + 1],ret[N + 1],wait[N + 1];
int a[21][N + 1];
int ques[N + 1];
int cur[21];
int findmin() {
int mn = INF;
int index = -1;
for (int i = 0; i < n; ++i) {
if (ret[a[i][cur[i]]] < mn) {
mn = ret[a[i][cur[i]]]; //剩余时间
index = i;
}
}
return index;
}
void mvtime(int x) { //第x列的current顾客完成了业务,所有列的current都需要把时间推移一下
int T = ret[a[x][cur[x]]];
for (int i = 0; i < n; ++i) {
ret[a[i][cur[i]]] -= T;
}
}
void doit() {
int index = 0;
for (int i = 0; i < n; ++i) a[i][0] = 0; //每一列有多少人
for (int i = 0; i < n; ++i) cur[i] = 1; //每一列在服务第几个人
for (int i = 1; i <= m && index<K; ++i) //开门时的状态
for (int j = 0; j < n && index < K; ++j)
{
a[j][i] = ++index; //矩阵里记录的是id
a[j][0]++;
}
while (index < K) {
int x=findmin(); //找到现在正在服务的最短时间在哪一列
//服务完了ta就走了,x就是最短的一列,下一个人肯定就会进入x
//接下来要把时间往后推移一下,方便之后findmin
mvtime(x);
a[x][0]++;
cur[x]++;
a[x][a[x][0]] = ++index;
}
//计算所有人的等待时间
for (int i = 0; i < n; ++i) {
int tot = 0;
for (int j = 1; j <= a[i][0]; ++j) {
tot += proc[a[i][j]];
wait[a[i][j]] = tot;
}
}
}
void print(int T,int tt) {
int h = T / 60;
int min = T % 60;
if (T-tt >= 9*60) { //开始时间已经超过17:00
cout << "Sorry";
return;
}
h += 8;
if (h <= 9)
cout << "0" << h << ":";
else cout << h << ":";
if (min <= 9)
cout << "0" << min;
else cout << min;
}
int main()
{
cin >> n >> m >> K >> Q;
for (int i = 1; i <= K; ++i) { cin >> proc[i]; ret[i] = proc[i]; }
for (int i = 1; i <= Q; ++i) cin >> ques[i];
doit();
for (int i = 1; i <= Q; ++i) {
print(wait[ques[i]],proc[ques[i]]);
if (i < Q) cout << endl;
}
return 0;
}
标签:PAT,cur,Level,int,业务,ret,模拟题,服务,proc 来源: https://blog.csdn.net/wu_tongtong/article/details/123616021