题目传送门
一眼模拟 顾客蜂拥而至不需要考虑到达时间 无脑排队不会插队,不需要对服务时间进行排序之类的操作 问题已经非常简化过于友好了
p
r
o
c
[
K
]
proc[K]
proc[K]:每个人需要的业务服务时间
r
e
t
[
K
]
ret[K]
ret[K]:每个人业务服务进度(剩余时间)
w
a
i
t
[
K
]
wait[K]
wait[K]:每个人的等待时间
a
[
N
]
[
K
]
a[N][K]
a[N][K]:N个队列的状态(从8:00开始)
c
u
r
[
N
]
cur[N]
cur[N]:N个队列正在服务的顾客(1~cur[i]-1是第i个队列已经服务过的顾客)
思路很简单,开门之前先把黄线以内的位置都安排好 每次都有一个业务服务时间剩余最少的人即将离开 我们只需要从每一列的当前服务对象中,找到这个 " 最快 " 的人即可 " 最快 " 的人完成业务后,就会离开银行 这时黄线后的第一个人就可以进入原先 " 最快 " 的人所在的那个队列继续等待
在 " 最快 " 的人完成业务时,所有队列的当前客户的业务服务进度都需要 " 前进 ",之后就重复寻找 " 最快 " 的人,让黄线外的人进入黄线
直到所有人都进入黄线在窗口前排队
那么每个人的等待时间如何计算? 想象一下当你在任何一个地方排队的时候 等待的时间只和你选择了排哪个队有关系 每当一个 " 最快 " 的人完成业务,所有人的时间都会推移,这一点其实已经体现在每个窗口当前客户的业务服务进度中 换句话说,每个人等待的时间就是 所在窗口,曾经排在ta前面的所有人,业务服务时间之和 这就可以解释我们为什么要用
a
[
N
]
[
K
]
a[N][K]
a[N][K]把在第
i
i
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) {
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;
a[j][0]++;
}
while (index < K) {
int 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) {
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;
}
|