华为OD机试 2023B卷题库疯狂收录中,刷题点这里
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
让我们来模拟一个消息队列的运作,有一个发布者和若干个消费者,发布者会在给定的时刻向消息队列发送消息。
消费者则会在给定的时刻订阅消息队列或取消订阅。
输入为两行。
第一行为2N 个正整数,代表发布者发送的N个消息的时刻和内容(为方便解折,消息内容也用正整教表示)。第一个数字是第一个消息的发送时刻,第二个数字是第一个消息的内容,以此类推。用例保证发送时刻不会重复,但注意消息并没有按照发送时刻排列。
第二行为2M个正整数,代表M个消费者订阅和取消订阅的时刻。第一个数字是第一个消费者订阅的时刻,第二个数字是第一个消费者取消订阅的时刻,以此类堆。用例保证每个消费者的取消订阅时刻大于订阅时刻,消费者按优先级 升席排列。
两行的数字都由空格分隔。N不超过100,M不超过10,每行的长度不超过1000字符。
输出为M行,依次为M个消费者收到的消息内容,消息内容按收到的顺序排列,且由空格分隔;
若某个消费者没有收到任何消息,则对应的行输出−1。
package com.guor.od;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class OdTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 发布者发送的N个消息的时刻和内容
int[] publisherArr = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
// M个消费者订阅和取消订阅的时刻
int[] consumerArr = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
// 发布者二维数组[时刻][内容]
int[][] publisherArrs = new int[publisherArr.length / 2][];
for (int i = 0, j = 0; i < publisherArr.length; i += 2) {
publisherArrs[j++] = new int[]{publisherArr[i], publisherArr[i + 1]};
}
// 按时刻排序
Arrays.sort(publisherArrs, (a, b) -> a[0] - b[0]);
// 消费者二维数组[订阅][取消]
int[][] consumerArrs = new int[consumerArr.length / 2][];
for (int i = 0, j = 0; i < consumerArr.length; i += 2) {
consumerArrs[j++] = new int[]{consumerArr[i], consumerArr[i + 1]};
}
// 消费关系列表
ArrayList<ArrayList<Integer>> relationList = new ArrayList<>();
for (int j = 0; j < consumerArrs.length; j++) {
relationList.add(new ArrayList<>());
}
// 遍历发布者,根据订阅和取消订阅关系将消息发送给消费者
for (int i = 0; i < publisherArrs.length; i++) {
for (int j = consumerArrs.length - 1; j >= 0; j--) {
// 判断消息是否被消费者订阅
if (publisherArrs[i][0] >= consumerArrs[j][0] && publisherArrs[i][0] < consumerArrs[j][1]) {
relationList.get(j).add(publisherArrs[i][1]);
break;
}
}
}
// 输出为M行,依次为M个消费者收到的消息内容
for (int i = 0; i < relationList.size(); i++) {
if (relationList.get(i).isEmpty()) {
System.out.println("-1");
} else {
String result = "";
for (Integer x : relationList.get(i)) {
result += x + " ";
}
System.out.println(result.trim());
}
}
}
}
2 200 1 100 4 400 5 500 3 300
1 7 2 3
100 300 400 500
200
消息100在1时刻到达,此时只有第一个消费者订阅,消息发送给它;
消息200在2时刻到达,此时两个消费者都订阅了,消息发送给优先级最高的第二个消费者;
消息300在时刻3到达,此时只有第一个消费者订阅,消息发送给它,
余下的消息按规则也是发送给第一个消费者。
下一篇:华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法
本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。