题目
https://pintia.cn/problem-sets/994805342720868352/problems/994805498207911936
题意
N个窗口,K个人去办事,每个窗口黄线内可容纳M个人,黄线外排一对,问每个人的完成时间
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
题解
N个窗口对应N个队列queue<>Q[i],黄线外一个队列queue<>T
先T中的人按顺序塞进Q中
之后每次找队头time最小的一个队列进行模拟,每pop掉一个,马上T中补上一个
虽然17:00关门,但17:00还在服务的人不能赶走~
code
/***************************
Hello World!
***************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
ll time;
ll id;
node(ll _t,ll _i):time(_t),id(_i){}
};
ll N,M,K,Q1;
queue<node>T;//排队
queue<node>Q[21];//窗口
ll ans[1006];
int d[1006];//每个人需要的时间
void print_time(int t,ll now)
{
if(now-d[t]>=540) {
printf("Sorry
");
return ;
}
int HH=8,MM=0;
HH+=now/60;
MM+=now%60;
printf("%02d:%02d
",HH,MM);
}
int main()
{
scanf("%lld%lld%lld%lld",&N,&M,&K,&Q1);
for(ll i=1;i<=K;i++) {
ll x; scanf("%lld",&x);
d[i]=x;
T.push(node(x,i));
}
//先塞满黄线内
ll f=0;
for(ll i=1;i<=M && !f;++i)//M行
{
for(ll j=1;j<=N;++j)
{
if(T.empty()) {
f=1;
break;
}
Q[j].push(T.front()); T.pop();
}
}
ll now=0;//8:00
ll aaa=K;
while(aaa--)
{
//找出所有队头的最小值
ll p=-1,mm=inf;
for(ll i=1;i<=N;++i) {
if(Q[i].empty()) continue;
ll temp=Q[i].front().time;
if(temp<mm) {
p=i; mm=temp;
}
}
//每个队头时间-mm
for(ll i=1;i<=N;++i)
{
if(Q[i].empty()) continue;
Q[i].front().time-=mm;
}
//记录时间,弹出Q[p]的队头
if(now<600) now+=mm;
ans[Q[p].front().id]=now;
Q[p].pop();
//如果黄线外还有人,加入Q[p]
if(!T.empty()) {
Q[p].push(T.front());
T.pop();
}
}
while(Q1--)
{
ll xx; scanf("%lld",&xx);
print_time(xx,ans[xx]);
}
return 0;
}
/***************************
The end!
***************************/