题目大意
银行有 N 个窗口,窗口前有一条黄线。并且有以下规则
- 黄线前每个窗口足够容纳 M 名顾客,因此若 N 个队伍都满了,则其余的乘客需要站在黄线外面等候
- 每名顾客都会选择最短的一队进入黄线区域(黄线内队伍中有顾客办理完成手续了),如果有两队人数一样,则从窗口号较小的队伍插入。
- 每名顾客都有自己办理业务的时间
- 业务办理从 8:00 开始,到 17:00 结束。
思路
两种情况:
- 黄线内的容量大于来办理业务的顾客。
将黄线内的顾客办理业务的时间存起来,因为头一批到达黄线内的顾客按照从左到右的顺序进入队伍就好。因此计算出各自的时间即可。
2.黄线内的容量小于来办理业务的顾客。
将黄线内的顾客办理业务的时间存起来,并计算出每个窗口在黄线内顾客办理完业务后的时间,用于计算后面的顾客办理业务的时间。然后找出每个窗口队伍第一个人办理业务最短的时间,弹出这个元素,并计算当前最短的队伍,然后将 在黄线后面等待的顾客 插入到这个队伍中,并计算对应的时间即可。
坑点
- 要考虑黄线容纳顾客的情况,可能可以完全容纳,也可能容纳不下
- 考虑 17:00 这个时间点。原题中的描述:
Note that since the bank is closed everyday after 17:00, for those customers who cannot be served before 17:00, you must output Sorry instead.
注意由于银行每天 17:00 之后下班,因此那些在 17:00 之前没有被服务到的顾客,你需要输出 Sorry。 - 注意处理 M 为 0 的情况
实现
#include <iostream>
#include <string.h>
#include <queue>
#include <map>
using namespace std;
int main() {
int N, M, K, Q;
int Time[1000]; // 存储每个顾客进店之后到办理结束后的时间,无法办理的值为 -1
// int yellow[10][20]; // 存储黄线内第一行的窗口处理时间
map<int, queue<int>> yellow;
int wait_time; // 存储每次输入的顾客办理业务时间
int sequence[1000], seq_index = 0; // 存储黄线之外顾客进入窗口的顺序
int number = 0; // 存储进入顾客的编号
int min_time = 999999, min_index = 0; // 存储最短办理时间 进入队列的顺序
int windows_time[20]; // 记录每个窗口的时间,用于计算每个顾客办理业务的时间
int min_length = 99999, min_len_index = 0; // 记录窗口前队伍的最短长度
cin >> N >> M >> K >> Q;
if (M == 0)
M = 1;
memset(windows_time, 0, sizeof(windows_time));
memset(Time, 0, sizeof(Time));
int circle = N*M < K ? N*M : K; // 处理办理业务的人数小于黄线内等待人数的情况
// 存储黄线内顾客的等待时间
for (int i = 0; i < circle; ++i) {
cin >> wait_time;
if (yellow.count(i % N) == 0) {
queue<int> temp;
temp.push(wait_time);
yellow.insert(pair<int, queue<int>>(i % N, temp));
} else {
map<int, queue<int>>::iterator iter = yellow.find(i % N);
iter->second.push(wait_time);
}
if (windows_time[i % N] >= 540)
Time[number++] = -1;
else {
windows_time[i % N] += wait_time;
Time[number++] = windows_time[i % N];
}
}
// 计算所有顾客的等待时间
for (int i = 0; i < K - N * M; ++i) {
cin >> wait_time;
for (map<int, queue<int>>::iterator iter = yellow.begin(); iter != yellow.end(); iter++) {
if (min_time > iter->second.front()) {
min_time = iter->second.front();
min_index = iter->first;
}
}
for (map<int, queue<int>>::iterator iter = yellow.begin(); iter != yellow.end(); iter++) {
if (min_index == iter->first) {
iter->second.pop();
} else {
iter->second.front() -= min_time;
}
if(min_length > iter->second.size()){
min_length = iter->second.size();
min_len_index = iter->first;
}
}
yellow.find(min_len_index)->second.push(wait_time);
if (windows_time[min_index] >= 540)
Time[number++] = -1;
else {
windows_time[min_index] += wait_time;
Time[number++] = windows_time[min_index];
}
min_length = min_time = 999999;
}
// 根据输入的序列输出时间
for (int i = 0; i < Q; ++i) {
int hour = 8, minutes = 0; // 定义时间,方便输出
cin >> wait_time; // 这里不想定义额外的变量,就使用这个了
minutes = Time[wait_time - 1];
hour += (minutes / 60);
minutes %= 60;
if (Time[wait_time - 1] == -1) {
cout << "Sorry";
} else {
if (hour < 10)
cout << "0" << hour << ":";
else
cout << hour << ":";
if (minutes < 10)
cout << "0" << minutes;
else
cout << minutes;
}
if (i < Q - 1)
cout << endl;
}
}