银行窗口排队,
N个窗口,黄线前每个窗口可以排M人,
已排队的人不能换队伍
黄线后的人没有站队
按照题意可知,黄线后的人在有人出队的时刻选择序号小的队伍开始排队
对于一个队伍来说,当黄线后还有没有入队的顾客时,每有一人到达服务结束时间,就会有一人入队
所以,我们可以确定每一队的成员编号、服务时间和顺序。
写的时候写出了很多BUG,
如:
加入队列时序号x = i + j * N写成 x = i + j * M
调试的时候把变量写错
超过时间跳出了,Sorry的时候没有加上ans[x]等于0的情况
注意:在17:00之前开始服务的,不输出Sorry
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
bool Sqrt(LL n) { return (LL)sqrt(n) * sqrt(n) == n; }
const double PI = acos(-1.0), ESP = 1e-10;
const LL INF = 99999999999999;
const int inf = 999999999, maxn = 24, maxk = 1e3 + 24, A = 540;
int N, M, K, Q;
int t[maxk], tc[maxn], ans[maxk];
map< int, vector<int> > mp;
map<int, int> In;
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
memset(ans, 0, sizeof ans);
memset(tc, 0, sizeof tc);
scanf("%d%d%d%d", &N, &M, &K, &Q);
for(int i = 1; i <= K; i++) scanf("%d", &t[i]);
int C = N * M;
for(int i = 1; i <= N; i++) {
for(int j = 0; j < M; j++) {
int x = i + j * N;
if(x <= K) {
tc[i] += t[x];
// printf("x = %d, tc[%d] = %d\n", x, i, tc[i]);
mp[tc[i]].push_back(x);
ans[x] = tc[i];
In[x] = i;
}
}
}
// puts("-----------");
int num = C + 1;
if(C < K) {
for(int i = 0; i <= A && num <= K; i++) {
if(mp[i].size()) {
for(auto u : mp[i]) {
int e = In[u];
tc[e] += t[num];
mp[tc[e]].push_back(num);
ans[num] = tc[e];
In[num] = e;
// printf("num = %d, tc[%d] = %d\n", num, e, tc[e]);
num++;
if(num > K) break;
}
}
}
}
while(Q--) {
int x; scanf("%d", &x);
int h = ans[x];
if((h - t[x] >= A) || (!h)) { puts("Sorry"); continue; }
int i = 8 + h / 60, j = h % 60;
printf("%02d:%02d\n", i, j);
}
// for(int i = 1; i <= K; i++) {
// printf("i = %d, In[i] = %d, ans[i] = %d\n", i, In[i], ans[i]);
// }
return 0;
}
/*
input:
output:
modeling:
methods:
complexity:
summary:
*/