华为OD机试 - 垃圾短信识别(Python/JS/C/C++ 2024 E卷 100分)

news2024/11/27 22:27:29

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

大⼤⼯对垃圾短信深恶痛绝,希望能够对垃圾短信发件者进⾏识别,为此,很多软件增加了垃圾短信的识别机制。经过分析,发现正常⽤⼾的短信通常具备交互性⽽垃圾短信往往都是⼤量单向的短信,按照如下规则进⾏垃圾短信识别:

本题中,发送者A符合以下条件之⼀的,则认为A是垃圾短信发送者:

A发送给B的直接短信中,没有发送给B的总数>5;
A发送的短信数>A接收的短信数 M>10;
如果M存在,A发送给C的短信数-A接收到C的短信数 N>5;

二、输入描述

第⼀⾏是条⽬总数,接下来是⼏⾏具体的条⽬,每个条⽬是⼀对ID,第⼀个数字是发送者ID,后⾯的数字是接收者ID,中间空格隔开,所有的ID都为⽆符号整数,ID最⼤值为100;

同⼀条⽬中,两个ID不会相同(即不会把⼀个⼈发消息⾃⼰)。

最后⼀⾏为指定的ID。

三、输出描述

输出该ID是否为垃圾短信发送者,并且按垃圾序列输出L与M的值(由于N值不唯⼀,不需要输出);输出均为空格分隔。

四、测试用例

1、输入

15
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
14 1
1 15
1

2、输出

true 13 13

3、说明

true 表示1是垃圾短信发送者,两个数字,代表发送者1对应的L和M值。
true 13 13 中间以一个空格分割。注意 true 是字符串输出。

五、解题思路

  1. 使用Scanner读取输入,包括短信记录的数量、具体记录、以及要检查的指定ID。
  2. 统计发送和接收信息:
    • 使用LinkedList存储发送和接收的ID。
    • 使用HashMap统计每个ID发送和接收的短信数量。
  3. 计算L值和M值:
    • L值:发送者发送给不同接收者的短信数量(不重复计算接收者)。
    • M值:发送者发送的短信数量减去接收的短信数量。
  4. 判断垃圾短信发送者:
    • 检查以下条件:
      • L值大于5。
      • M值大于10。
      • 对于每个发送给的接收者,检查发送数量与接收数量的差值是否大于5。
  5. 输出结果:打印结果,格式为true/false L M。

六、Python算法源码

# 导入所需的模块
from collections import defaultdict

def get_result(tid, arr):
    # 用于存储发送和接收的ID
    send = []
    receive = []
    
    # 统计发送和接收的数量
    send_count = defaultdict(int)  # 发送统计
    receive_count = defaultdict(int)  # 接收统计

    # 处理每条短信记录
    for sid, rid in arr:
        # 如果发送者是指定的ID
        if sid == tid:
            send.append(rid)  # 添加接收者ID到发送列表
            send_count[rid] += 1  # 统计发送给接收者的次数

        # 如果接收者是指定的ID
        if rid == tid:
            receive.append(sid)  # 添加发送者ID到接收列表
            receive_count[sid] += 1  # 统计接收到的次数

    # 使用集合去重
    send_set = set(send)
    receive_set = set(receive)

    # 计算连接的数量(即同时发送和接收的ID)
    connect = send_set.intersection(receive_set)

    # 计算L和M值
    l = len(send_set) - len(connect)  # L值
    m = len(send) - len(receive)  # M值

    # 判断是否为垃圾短信发送者
    is_spammers = l > 5 or m > 10

    # 如果不是垃圾发送者,检查其他条件
    if not is_spammers:
        for rid in send_set:
            # 检查发送给每个接收者的差值是否大于5
            if send_count[rid] - receive_count[rid] > 5:
                is_spammers = True
                break

    # 返回结果
    return f"{is_spammers} {l} {m}"

# 主程序入口
if __name__ == "__main__":
    # 读取条目总数
    n = int(input())
    arr = []

    # 读取每条短信记录
    for _ in range(n):
        arr.append(tuple(map(int, input().split())))

    # 读取指定的ID
    id = int(input())

    # 调用计算结果的方法并输出
    print(get_result(id, arr))

七、JavaScript算法源码

function getResult(tid, arr) {
    // 用于存储发送和接收的ID
    const send = [];
    const receive = [];
    
    // 统计发送和接收的数量
    const sendCount = new Map();  // 发送统计
    const receiveCount = new Map();  // 接收统计

    // 处理每条短信记录
    for (let [sid, rid] of arr) {
        // 如果发送者是指定的ID
        if (sid === tid) {
            send.push(rid);  // 添加接收者ID到发送列表
            sendCount.set(rid, (sendCount.get(rid) || 0) + 1);  // 统计发送给接收者的次数
        }

        // 如果接收者是指定的ID
        if (rid === tid) {
            receive.push(sid);  // 添加发送者ID到接收列表
            receiveCount.set(sid, (receiveCount.get(sid) || 0) + 1);  // 统计接收到的次数
        }
    }

    // 使用Set去重
    const sendSet = new Set(send);
    const receiveSet = new Set(receive);

    // 计算连接的数量(即同时发送和接收的ID)
    const connect = [...sendSet].filter(id => receiveSet.has(id));

    // 计算L和M值
    const l = sendSet.size - connect.length;  // L值
    const m = send.length - receive.length;  // M值

    // 判断是否为垃圾短信发送者
    let isSpammers = l > 5 || m > 10;

    // 如果不是垃圾发送者,检查其他条件
    if (!isSpammers) {
        for (let rid of sendSet) {
            // 检查发送给每个接收者的差值是否大于5
            if ((sendCount.get(rid) || 0) - (receiveCount.get(rid) || 0) > 5) {
                isSpammers = true;
                break;
            }
        }
    }

    // 返回结果
    return `${isSpammers} ${l} ${m}`;
}

// 主程序入口
const input = require('fs').readFileSync('/dev/stdin', 'utf-8').trim().split('\n');
const n = parseInt(input[0]);
const arr = input.slice(1, n + 1).map(line => line.split(' ').map(Number));
const id = parseInt(input[n + 1]);

// 调用计算结果的方法并输出
console.log(getResult(id, arr));

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_USERS 100

// 统计发送和接收的数量
int sendCount[MAX_USERS + 1];
int receiveCount[MAX_USERS + 1];

int getResult(int tid, int arr[][2], int n) {
    // 用于存储发送和接收的唯一ID
    int sendSet[MAX_USERS + 1] = {0}; // 发送的接收者ID
    int receiveSet[MAX_USERS + 1] = {0}; // 接收的发送者ID
    int sendSize = 0, receiveSize = 0;

    // 处理每条短信记录
    for (int i = 0; i < n; i++) {
        int sid = arr[i][0]; // 发送者ID
        int rid = arr[i][1]; // 接收者ID

        // 如果发送者是指定的ID
        if (sid == tid) {
            sendSet[rid] = 1; // 标记该接收者ID
            sendCount[rid]++; // 统计发送给接收者的次数
            sendSize++; // 增加发送数量
        }

        // 如果接收者是指定的ID
        if (rid == tid) {
            receiveSet[sid] = 1; // 标记该发送者ID
            receiveCount[sid]++; // 统计接收到的次数
            receiveSize++; // 增加接收数量
        }
    }

    // 计算连接的数量(即同时发送和接收的ID)
    int connect = 0;
    for (int i = 1; i <= MAX_USERS; i++) {
        if (sendSet[i] && receiveSet[i]) {
            connect++; // 计算同时发送和接收的数量
        }
    }

    // 计算L和M值
    int l = sendSize - connect; // L值
    int m = 0;
    for (int i = 1; i <= MAX_USERS; i++) {
        m += sendCount[i]; // 发送的总数
    }
    m -= receiveSize; // M值

    // 判断是否为垃圾短信发送者
    int isSpammers = (l > 5 || m > 10);

    // 如果不是垃圾发送者,检查其他条件
    if (!isSpammers) {
        for (int i = 1; i <= MAX_USERS; i++) {
            if (sendSet[i] && (sendCount[i] - receiveCount[i] > 5)) {
                isSpammers = 1; // 标记为垃圾短信发送者
                break;
            }
        }
    }

    // 输出结果
    printf("%s %d %d\n", isSpammers ? "true" : "false", l, m);
    return 0;
}

// 主程序入口
int main() {
    int n;
    scanf("%d", &n);
    int arr[n][2];

    // 读取每条短信记录
    for (int i = 0; i < n; i++) {
        scanf("%d %d", &arr[i][0], &arr[i][1]);
    }

    // 读取指定的ID
    int id;
    scanf("%d", &id);

    // 调用计算结果的方法
    getResult(id, arr, n);
    return 0;
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>

using namespace std;

// 计算结果的函数
string getResult(int tid, const vector<pair<int, int>>& arr) {
    unordered_set<int> sendSet;  // 用于存储发送的接收者ID
    unordered_set<int> receiveSet;  // 用于存储接收的发送者ID
    unordered_map<int, int> sendCount;  // 统计发送给每个接收者的次数
    unordered_map<int, int> receiveCount;  // 统计接收到的次数

    // 处理每条短信记录
    for (const auto& ele : arr) {
        int sid = ele.first;  // 发送者ID
        int rid = ele.second;  // 接收者ID

        // 如果发送者是指定的ID
        if (sid == tid) {
            sendSet.insert(rid);  // 添加接收者ID到发送集合
            sendCount[rid]++;  // 统计发送给接收者的次数
        }

        // 如果接收者是指定的ID
        if (rid == tid) {
            receiveSet.insert(sid);  // 添加发送者ID到接收集合
            receiveCount[sid]++;  // 统计接收到的次数
        }
    }

    // 计算连接的数量(即同时发送和接收的ID)
    int connect = 0;
    for (int id : sendSet) {
        if (receiveSet.count(id)) {
            connect++;  // 统计同时发送和接收的ID
        }
    }

    // 计算L和M值
    int l = sendSet.size() - connect;  // L值
    int m = sendCount.size() - receiveSet.size();  // M值

    // 判断是否为垃圾短信发送者
    bool isSpammers = (l > 5 || m > 10);

    // 如果不是垃圾发送者,检查其他条件
    if (!isSpammers) {
        for (int id : sendSet) {
            if (sendCount[id] - receiveCount[id] > 5) {
                isSpammers = true;  // 标记为垃圾短信发送者
                break;
            }
        }
    }

    // 返回结果
    return to_string(isSpammers) + " " + to_string(l) + " " + to_string(m);
}

// 主程序入口
int main() {
    int n;
    cin >> n;  // 读取条目总数
    vector<pair<int, int>> arr(n);

    // 读取每条短信记录
    for (int i = 0; i < n; i++) {
        cin >> arr[i].first >> arr[i].second;  // 读取发送者和接收者ID
    }

    // 读取指定的ID
    int id;
    cin >> id;

    // 调用计算结果的方法并输出
    cout << getResult(id, arr) << endl;
    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2189758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8645 归并排序(非递归算法)

### 思路 非递归归并排序通过逐步合并相邻的子数组来实现排序。每次合并后输出当前排序结果。 ### 伪代码 1. 读取输入的待排序关键字个数n。 2. 读取n个待排序关键字并存储在数组中。 3. 对数组进行非递归归并排序&#xff1a; - 初始化子数组的大小curr_size为1。 - 逐…

手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]

有时候&#xff0c;您会被锁定在自己的 Android 设备之外&#xff0c;而且似乎不可能重新进入。 一个例子就是你买了一部二手手机&#xff0c;后来发现无法使用。另一种情况是你忘记了屏幕锁定密码和用于验证密码的 Google 帐户凭据。这种情况很少见&#xff0c;但确实会发生&…

vite学习教程01、vite构建vue2

文章目录 前言一、vite初始化项目二、修改配置文件2.1、修改main.js文件2.2、修改App.vue文件2.3、修改helloworld.vue2.4、修改vite.conf.js2.5、修改vue版本--修改package.json文件 三、安装vue2和vite插件四、启动服务资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝3W&…

网站建设中,静态网页和动态网页分别是什么,有什么区别

在现代网页设计和开发中&#xff0c;理解静态网页与动态网页的区别是至关重要的。 静态网页 定义&#xff1a; 静态网页是指内容固定不变&#xff0c;用户访问时服务器直接返回存储在服务器上的HTML文件。这些页面通常以.html、.htm等扩展名结尾&#xff0c;不包含特殊符号如“…

多模态大模型调研

Clip的泛化能力超强 压缩图片 GPT4 NLP与CV的区分是历史阶段性的产物&#xff0c;有了vit/transformer之后&#xff0c;两者的区分不再明显 Glip 应用于目标检测

Hadoop之WordCount测试

1、Hadoop简介&#xff1a; Hadoop是Apache旗下的一个用Java语言实现的开源软件框架&#xff0c;是一个开发和运行处理大规模数据的软件平台。 Hadoop的核心组件包括Hadoop分布式文件系统&#xff08;HDFS&#xff09;和MapReduce编程模型。HDFS是一个高度容错的系统&#xf…

CSS3练习--电商web

免责声明&#xff1a;本文仅做分享&#xff01; 目录 小练--小兔鲜儿 目录构建 SEO 三大标签 Favicon 图标 布局网页 版心 快捷导航&#xff08;shortcut&#xff09; 头部&#xff08;header&#xff09; logo 导航 搜索 购物车 底部&#xff08;footer&#xff0…

Vue工程化开发

Vue工程化开发 一、工程化开发和脚手架 1.开发Vue的两种方式 核心包传统开发模式&#xff1a;基于html / css / js 文件&#xff0c;直接引入核心包&#xff0c;开发 Vue。工程化开发模式&#xff1a;基于构建工具&#xff08;例如&#xff1a;webpack&#xff09;的环境中开…

【2024版本】Mac/Windows IDEA安装教程

IDEA 2024版本真的很强大&#xff0c;此外JDK发布了最新稳定版 JDK21 &#xff0c;只有新版本支持JDK 21、JDK22。原来数据库插件不支持redis等一些NoSql的数据库的连接&#xff0c;如果要使用需要自己单独装收费的插件。直接打开idea就很吃内存了&#xff0c;再打开其他一大堆…

计算机毕业设计 网上书店系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

基于facefusion的换脸

FaceFusion是一个引人注目的开源项目&#xff0c;它专注于利用深度学习技术实现视频或图片中的面部替换。作为下一代换脸器和增强器&#xff0c;FaceFusion在人脸识别和合成技术方面取得了革命性的突破&#xff0c;为用户提供了前所未有的视觉体验。 安装 安装基础软件 安装…

gdb 调试 linux 应用程序的技巧介绍

使用 gdb 来调试 Linux 应用程序时&#xff0c;可以显著提高开发和调试的效率。gdb&#xff08;GNU 调试器&#xff09;是一款功能强大的调试工具&#xff0c;适用于调试各类 C、C 程序。它允许我们在运行程序时检查其状态&#xff0c;设置断点&#xff0c;跟踪变量值的变化&am…

华为OD机试 - 可活动的最大网格点数目 - 广度优先搜索BFS(Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

【LLM】Agent在智能客服的实践(AI agent、记忆、快捷回复 | ReAct)

note 内容概况&#xff1a;结合京粉app学习agent的实践 Agent架构&#xff1a;通过模型训练提升LLM识别工具的准确性&#xff1b;设计可扩展并安全可控的agent架构扩展业务能力。记忆&#xff1a;多轮对话应用中如何组织、存储和检索记忆来提升大模型对用户的理解。快捷回复&…

【JAVA开源】基于Vue和SpringBoot的水果购物网站

本文项目编号 T 065 &#xff0c;文末自助获取源码 \color{red}{T065&#xff0c;文末自助获取源码} T065&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

生产消费者模式

6. 生产消费者模式 Producer-Consumer模式 6.1 概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯&#xff0c;而通过阻塞队列来进行通讯&#xff0c;所以生产者生产完数据之后不用等待消费者处理&#xff0c;直接扔…

解决TortoiseGit文件夹图标不见的问题。

打开注册表&#xff0c;\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\ &#xff0c;把里面的TortoiseGit开头的前面多补几个空格&#xff0c;让它们排到靠前的位置&#xff0c;然后重启电脑。 据说是windows只有前11/…

在线点餐堂食系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;商品管理&#xff0c;基础数据管理&#xff0c;论坛管理&#xff0c;公告信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品&#xff0c;…

AL生成文章标题指定路径保存:创新工具助力内容创作高效启航

在信息爆炸的时代&#xff0c;一个吸引人的标题是文章成功的第一步。它不仅要准确概括文章内容&#xff0c;还要能激发读者的好奇心&#xff0c;促使他们点击阅读。随着人工智能技术的飞速发展&#xff0c;AL生成文章标题功能正逐渐成为内容创作者的新宠&#xff0c;看看它是如…

Mysql数据库--聚合查询、分组查询、联合查询(不同的连接方式)

文章目录 1.查询的进阶版1.1查询搭配插入进行使用1.2聚合查询1.3group by分组查询1.4联合查询之笛卡尔积1.5左外连接&#xff0c;右外连接介绍join on1.6自连表 1.查询的进阶版 1.1查询搭配插入进行使用 我们首先创建两张表&#xff0c;一个叫做student,一个叫做student2,两个…