目录
- 专栏导读
- 一、题目描述
- 二、输入描述
- 三、输出描述
- 1、输入
- 2、输出
- 3、说明
- 四、解题思路
- 五、Java算法源码
- 六、效果展示
- 1、输入
- 2、输出
- 3、说明
华为OD机试 2024C卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷+C卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
大众对垃圾短信深恶痛绝,希望能对垃圾短信发送者进行识别,为此,很多软件增加 了垃圾短信识别机制。经分析,发现正常用户的短信通常具备交互性,而垃圾短信往 往都是大量单向的短信,按照如下规则进行垃圾短信识别:
本题中,发送者A符合以下条件之一的,则认为A是垃圾短信发送者:
① A 发送短信的接收者中,没有发过短信给A的人数 L > 5;
② A 发送的短信数 - A接收的短信数 M > 10;
③ 如果存在 X,A 发送给 X 的短信数 - A 接收到X的短信数N > 5。
二、输入描述
第一行为条目数目,接下来几行是具体的条目,每个条目,是一对ID,第一个数字是发送者ID,后面的数字是接收者ID,中间空格隔开,所有的ID都为无符号整型,ID最大值为100;
同一个条目中,两个ID不会相同(即不会自己给自己发消息);
最后一行为指定的ID。
三、输出描述
输出该ID是否为垃圾短信发送者(是输出 true,否则输出 false),并且按序列输出L、M的值(由于N值不唯一,不需要输出);
输出均为宇符串。
1、输入
8
1 2
1 3
1 4
1 5
1 6
6 1
5 2
6 3
1
2、输出
false 4 1
3、说明
- 输出该ID是否为垃圾短信发送者(是输出 true,否则输出 false),并且按序列输出L、M的值;
- 没有发过短信给A的人数L,A接收的短信数 M。
没有发过短信给A的人数L为4,A接收的短信数 M为1。
四、解题思路
此题还是很简单的,根据题意解析即可。
- 定义没有发过短信给A的人数L、A接收的短信数 M、A 发送给 X 的短信数X、A 接收到X的短信数N;
- 遍历A发送的短信关系aToList;
- 获取接收A短信的用户的短信发送信息;
- 如果未给A发送,则没有发过短信给A的人数L++;
- 否则A接收的短信数 M++;
- 获取A 发送给 X 的短信数X、A 接收到X的短信数N;
- 如果存在 X,A 发送给 X 的短信数 - A 接收到X的短信数N > 5,则视为垃圾短信发送者,输出true,不再计算N值;
- 根据①、②、③判断条件,判断是否为垃圾短信发送者,满足一个即为垃圾短信发送者:
- A 发送短信的接收者中,没有发过短信给A的人数 L > 5;
- A 发送的短信数 - A接收的短信数 M > 10;
- 如果存在 X,A 发送给 X 的短信数 - A 接收到X的短信数N > 5;
- 输出该ID是否为垃圾短信发送者(是输出 true,否则输出 false),并且按序列输出L、M的值。
五、Java算法源码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = Integer.valueOf(sc.nextLine());
Map<Integer, List<Integer>> map = new HashMap<>();
for (int i = 0; i < n; i++) {
int[] arr = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
List<Integer> list = map.getOrDefault(arr[0], new ArrayList<>());
list.add(arr[1]);
map.put(arr[0], list);
}
Integer A = Integer.valueOf(sc.nextLine());
List<Integer> aToList = map.get(A);
// 1. A 发送短信的接收者中,没有发过短信给A的人数 L > 5
// 没有发过短信给A的人数
int L = 0;
// A接收的短信数 M
int M = 0;
// A 发送给 X 的短信数
int X = 0;
// A 接收到X的短信数N
int N = 0;
// 3.如果存在 X,A 发送给 X 的短信数 - A 接收到X的短信数N > 5
boolean flag = false;
for (Integer num : aToList) {
List<Integer> toAList = map.getOrDefault(num, new ArrayList<>());
if (!toAList.contains(A)) {
L++;
} else {
M++;
// 3.如果存在 X,A 发送给 X 的短信数 - A 接收到X的短信数N > 5
if(!flag){
// A 发送给 X 的短信数
X = Collections.frequency(aToList, num);
// A 接收到X的短信数N
N = Collections.frequency(toAList, A);
if(X - N > 5){
flag = true;
}
}
}
}
// 2. A 发送的短信数 - A接收的短信数 M > 10
// A 发送的短信数
int aSend = aToList.size();
// 没有发过短信给A的人数L,A接收的短信数 M
StringBuilder builder = new StringBuilder();
if (L > 5 || aSend - M > 10 || flag) {
builder.append("true").append(" ").append(L).append(" ").append(M);
}else{
builder.append("false").append(" ").append(L).append(" ").append(M);
}
System.out.println(builder);
}
六、效果展示
1、输入
12
1 2
1 3
1 4
1 5
1 6
1 7
1 8
6 1
7 1
8 1
5 2
6 3
1
2、输出
false 4 3
3、说明
- 输出该ID是否为垃圾短信发送者(是输出 true,否则输出 false),并且按序列输出L、M的值;
- 没有发过短信给A的人数L,A接收的短信数 M。
没有发过短信给A的人数L为4,A接收的短信数 M为3。
🏆下一篇:华为OD机试 - 最长的顺子 - 感谢@禁止你发言提供的更简便算法(Java 2023 B卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷+C卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。