题目大意
模拟一个银行等待队列,银行有n个窗口,每个窗口前有m个位置,不能进入位置的客户按照顺序id等待,当有位置空出时进入,给出被询问客户的服务完成时间。
注意:银行在17:00关门,不能在此前被服务的人只能"Sorry"了。
注意注意注意:这里是指在17:00未被服务,若服务已经开始,便将服务完成。
思路
用一个循环模拟时间演进,服务完一个客户就让下一个客户进入排队。
代码如下
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
using namespace std;
void print_time(int t)
{ //时间输出函数
if (t == -1)
{
printf("Sorry\n");
return;
}
int h, m;
h = t / 60 + 8;
m = t % 60;
printf("%02d:%02d\n", h, m);
}
int main() {
int n, m, k, q;
cin >> n >> m >> k >> q;
vector<vector<int> > bank(n, vector<int>(m));//银行窗口
vector<vector<int> > server_customer_id(n, vector<int>(m));//记录当前服务客户的id
vector<int> use_time(k + 1);
vector<int> end_time(k + 1,-1);//-1标记未能服务
for (int i = 1; i <= k; i++)
scanf("%d", &use_time[i]);
int customer_id = 1, now_time = 0;
for(int j = 0;j < m;j++)
for (int i = 0; i < n; i++)
{
if (customer_id <= k)//应对客户少于窗口数
{
server_customer_id[i][j] = customer_id;
bank[i][j] = use_time[customer_id++];
}
}
bool server_over;
while (++now_time <= 540)
{
server_over = true;//记录是否全部客户服务完成
for (int i = 0; i < n; i++)
{
if (bank[i].size())
{ //窗口i仍有客户
server_over = false;
bank[i][0]--;
if (bank[i][0] == 0)
{
end_time[server_customer_id[i][0]] = now_time;
server_customer_id[i].erase(server_customer_id[i].begin());
bank[i].erase(bank[i].begin());
if (customer_id <= k)//客户数为k
{
server_customer_id[i].push_back(customer_id);
bank[i].push_back(use_time[customer_id++]);
}
}
}
}
if (server_over)
break;
}
for (int i = 0; i < n; i++)
{
if (bank[i].size() && bank[i][0] != use_time[server_customer_id[i][0]])
{ //处理17:00时已经开始服务的客户
end_time[server_customer_id[i][0]] = 540 + bank[i][0];
}
}
for (int i = 1; i <= q; i++)
{
scanf("%d", &customer_id);
print_time(end_time[customer_id]);
}
return 0;
}
/*
2 2 7 5
1 2 6 4 3 533 2
3 4 5 6 7
*/