jmu-Java-PTA题解 (6.2- 银行业务队列简单模拟 ) 网安2312陈卓
问题要求
设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。
输入格式:
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。
输出格式:
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。
输入样例:
8 2 1 3 9 4 11 13 15
输出样例:
1 3 2 9 11 4 13 15
关键点
- 窗口处理速度差异:A窗口每处理两个顾客,B窗口才能处理一个顾客。
- 顾客编号规则:奇数编号的顾客去A窗口,偶数编号的顾客去B窗口。
- 输出顺序:A窗口的顾客优先输出,当两个窗口同时处理完顾客时。
解题步骤
第一步:初始化数据结构
为了模拟两个窗口,可以使用两个LinkedList来分别存储A窗口和B窗口的顾客。
LinkedList<Integer> lista = new LinkedList<>();
LinkedList<Integer> listb = new LinkedList<>();
第二步:分配顾客到窗口
遍历输入的顾客编号,根据编号的奇偶性将顾客分配到对应的窗口队列中。
for (int i = 0; i < n; i++) {
int e = in.nextInt();
if (e % 2 != 0) {
lista.add(e);
} else {
listb.add(e);
}
}
第三步:处理顾客并输出
通过一个循环来模拟窗口处理顾客的过程。在这个循环中,根据题目要求我们需要处理以下几点:
- A窗口的处理速度是B窗口的两倍,因此我们需要一个计数器
count来记录A窗口处理的顾客数量。 - 当
count达到2时,表示A窗口处理了两个顾客,这时我们也需要处理B窗口的一个顾客。 - 输出顾客编号时,需要注意格式,尤其是最后一个编号后不能有多余的空格。
int count = 1;
int flag = 1; // 用于控制输出格式
while (lista.size() != 0 && listb.size() != 0) {
if (count != 2) {
// 输出A窗口的顾客
System.out.print((flag == 1 ? "" : " ") + lista.get(0));
lista.remove(0);
count++;
} else {
// 输出A窗口和B窗口的顾客
System.out.print(" " + lista.get(0));
lista.remove(0);
System.out.print(" " + listb.get(0));
listb.remove(0);
count = 1;
}
flag = 2;
}
第四步:处理剩余顾客
在主循环结束后,可能还有顾客在某个窗口的队列中等待处理。我们需要分别处理这两个队列中的剩余顾客。
while (lista.size() != 0) {
System.out.print((flag == 1 ? "" : " ") + lista.get(0));
lista.remove(0);
flag = 2;
}
while (listb.size() != 0) {
System.out.print((flag == 1 ? "" : " ") + listb.get(0));
listb.remove(0);
}
整体流程图:

整体代码:
import java.util.Scanner;
import java.util.LinkedList;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
LinkedList<Integer> lista = new LinkedList<>();
LinkedList<Integer> listb = new LinkedList<>();
for(int i=0;i<n;i++){
int e = in.nextInt();
if(e%2!=0){
lista.add(e);
}else{
listb.add(e);
}
}
int count=1;
int flag = 1;
while(lista.size()!=0&&listb.size()!=0){
if(count!=2){
if(flag==1){
flag=2;
System.out.print(lista.get(0));
}else{
System.out.print(" "+lista.get(0));
}
lista.remove(0);
count += 1;
}else{
count = 1;
System.out.print(" "+lista.get(0));
lista.remove(0);
System.out.print(" "+listb.get(0));
listb.remove(0);
}
}
while(lista.size()!=0){
if(flag==1){
flag=2;
System.out.print(lista.get(0));
}else{
System.out.print(" "+lista.get(0));
}
lista.remove(0);
}
while(listb.size()!=0){
if(flag==1){
flag=2;
System.out.print(listb.get(0));
}else{
System.out.print(" "+listb.get(0));
}
listb.remove(0);
}
}
}
思考:在解决银行业务队列模拟问题时,我采用LinkedList模拟业务窗口,LinkedList进行插入和删除操作时,时间复杂度为O(1),在处理顾客入队和出队操作时能高效完成。而ArrayList在插入和删除元素时,可能需要移动大量元素,时间复杂度为 O(n),效率较低。当然,也可以使用其它集合框架容器如vector,Hashmap等模拟队列,但同理数组在动态扩展时可能时间复杂度较大,操作比LinkedList复杂。在实际应用中,若顾客数量波动大,LinkedList灵活性更佳。

浙公网安备 33010602011771号