题目描述
【银行插队】
某银行将客户分为了若干个优先级, 1 级最高, 5 级最低,当你需要在银行办理业务时,优先级高的人
随时可以插队到优先级低的人的前面。
现在给出一个人员到来和银行办理业务的时间序列,请你在每次银行办理业务时输出客户的编号。如果
同时有多位优先级相同且最高的客户,则按照先来后到的顺序办理。
输入描述
输入第一行是一个正整数 n ,表示输入的序列中的事件数量。(1 ≤ n ≤ 500)
接下来有 n 行,每行第一个字符为 a 或 p 。
当字符为 a 时,后面会有两个的正整数 num 和 x ,表示到来的客户编号为 num ,优先级为 x ;
当字符为 p 时,表示当前优先级最高的客户去办理业务。
输出描述
输出包含若干行,对于每个 p , 输出一行,仅包含一个正整数 num , 表示办理业务的客户编号。
注意事项
1.如果没有p输入,则没有客户编号输出
2.如果有多个p输入,则对应应该有多个客户编号输出,前提是p的数量不能多于还没有办理业务的客户
人数。当p输入的个数多余代办业务客户人数,则多余的p输入可以忽略
用例
用例1
输入 | 4 a 1 3 a 2 2 a 3 2 p |
---|---|
输出 | 2 |
说明 | 2号代办业务的客户的优先级最高,且最先到达 |
用例2
输入 | 8 a 1 3 a 2 2 a 3 2 p a 4 3 a 5 1 a 6 2 p |
---|---|
输出 | 2 5 |
说明 | 第一次2号代办业务的客户的优先级最高,且最先到达 第二次5号代办业务的客户的优先级最高 |
解题思路
题目中给出了一些客户到来和银行办理业务的时间序列,每个客户具有一个优先级(1-5,1 最高,5 最
低),优先级高的客户随时可以插队到优先级低的客户前面。因此我们需要将每个客户的信息记录下
来,维护多个队列,按照不同的优先级存储客户编号。
当有客户到来时,将其加入对应优先级的队列。同时需要更新当前最高优先级,也就是找到当前所有队
列中优先级最高的客户,以便在办理业务时能够优先处理他们。
当有客户去办理业务时,从当前最高优先级队列中取出一个客户,输出其编号。如果当前最高优先级队
列已空,则需要寻找下一个最高优先级,即从当前最高优先级的下一个优先级开始查找,如果该优先级
队列不为空,则更新当前最高优先级为该优先级;否则继续往下查找,直到找到一个非空队列,或者查
找到最低优先级(5)。
需要注意的是,本题需要注意处理多个连续的 p 输入,也就是输出多个办理业务的客户编号。如果当前
没有客户可办理业务,需要跳过该 p 输入,否则需要输出对应的客户编号。输出时可以使用
StringBuilder 来保存结果,避免每次输出都要进行 I/O 操作,提高效率。
综上所述,本题可以使用队列来实现。在输入每个客户信息时,将其加入对应优先级的队列;在输入 p
时,从当前最高优先级队列中取出一个客户编号,输出其编号,并更新当前最高优先级。最后输出所有
办理业务的客户编号即可。
参考代码
import java.util.*;
public class BankPriorityQueue {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Queue<Integer>[] queues = new LinkedList[5];
for (int i = 0; i < 5; i++) {
queues[i] = new LinkedList<Integer>();
}
int curLevel = 5; // 当前最高优先级
int count = 0; // 记录已经办理的人数
StringBuilder sb = new StringBuilder(); // 用于保存输出结果
for (int i = 0; i < n; i++) {
char c = sc.next().charAt(0);
if (c == 'a') {
int num = sc.nextInt();
int level = sc.nextInt();
queues[level-1].offer(num); // 将客户编号加入对应优先级的队列
curLevel = Math.min(curLevel, level); // 更新当前最高优先级
} else if (c == 'p') {
if (curLevel == 5) continue; // 当前没有客户可办理业务
int num = queues[curLevel-1].poll(); // 取出当前最高优先级队列中的客户编号
sb.append(num).append('\n');
if (queues[curLevel-1].isEmpty()) { // 如果当前最高优先级队列已空,则需要更新当前最高优先级
for (int j = curLevel; j < 5; j++) {
if (!queues[j].isEmpty()) {
curLevel = j+1;
break;
}
if (j == 4) curLevel = 5;
}
}
}
}
System.out.print(sb.toString());
}
}