java解法

每条消息以 (sender, receiver) 的形式表示,分别为发送方和接收方的 ID。
给定一个目标用户 ID tid,需要判定该用户是否为垃圾发送者。
垃圾发送者的判定规则:
tid 发送的接收方中,有超过 5 个未回复的接收方。
tid 总发送消息数量减去总接收消息数量超过 10。
对任意接收方,如果 tid 向其发送的消息数量比从其接收的消息数量多 5 条以上,则为垃圾发送者。
算法设计

使用 集合 和 映射 数据结构统计消息的发送和接收关系:
sentTo:tid 发送消息的所有接收方。
receivedFrom:tid 接收消息的所有发送方。
sendCount:tid 对每个接收方发送的消息数量。
receiveCount:每个发送方对 tid 发送的消息数量。
根据统计数据,计算以下结果:
未回复的接收方数量 l。
总发送消息数量与接收消息数量的差值 m。
是否满足垃圾发送者判定规则。
实现细节

使用 SpamDetector 类封装判定逻辑,包括消息处理、垃圾发送者判定,以及结果计算方法。
在主函数中读取输入,调用 SpamDetector 执行判定。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 读取消息记录数
        int n = scanner.nextInt();

        // 存储消息记录的列表
        List<int[]> messages = new ArrayList<>();

        // 读取消息记录 (sender, receiver)
        for (int i = 0; i < n; i++) {
            int[] entry = new int[2];
            entry[0] = scanner.nextInt(); // 发送方
            entry[1] = scanner.nextInt(); // 接收方
            messages.add(entry);
        }

        // 读取目标用户 ID
        int targetId = scanner.nextInt();

        // 调用方法检查垃圾发送者并输出结果
        System.out.println(checkSpammer(targetId, messages));
    }

    /**
     * 检查指定用户是否为垃圾发送者
     *
     * @param tid      目标用户 ID
     * @param messages 消息记录列表
     * @return 判定结果字符串,格式为 "true/false l m"
     */
    public static String checkSpammer(int tid, List<int[]> messages) {
        // 创建垃圾发送者检测器对象
        SpamDetector detector = new SpamDetector(tid);

        // 处理每条消息记录
        for (int[] msg : messages) {
            detector.processMessage(msg[0], msg[1]);
        }

        // 返回判定结果
        return detector.isSpammer() + " " + detector.getL() + " " + detector.getM();
    }
}

/**
 * 垃圾发送者检测器类
 */
class SpamDetector {
    private int tid; // 目标用户 ID
    private Set<Integer> sentTo = new HashSet<>(); // `tid` 发送的接收方集合
    private Set<Integer> receivedFrom = new HashSet<>(); // `tid` 接收的发送方集合
    private Map<Integer, Integer> sendCount = new HashMap<>(); // `tid` 向每个接收方发送的消息数量
    private Map<Integer, Integer> receiveCount = new HashMap<>(); // 每个发送方向 `tid` 发送的消息数量

    // 构造函数初始化目标用户 ID
    public SpamDetector(int tid) {
        this.tid = tid;
    }

    /**
     * 处理单条消息记录
     *
     * @param sender   发送方 ID
     * @param receiver 接收方 ID
     */
    public void processMessage(int sender, int receiver) {
        if (sender == tid) { // 如果发送方是目标用户
            sentTo.add(receiver); // 添加接收方到发送集合
            sendCount.put(receiver, sendCount.getOrDefault(receiver, 0) + 1); // 更新发送数量
        } else if (receiver == tid) { // 如果接收方是目标用户
            receivedFrom.add(sender); // 添加发送方到接收集合
            receiveCount.put(sender, receiveCount.getOrDefault(sender, 0) + 1); // 更新接收数量
        }
    }

    /**
     * 判定是否为垃圾发送者
     *
     * @return 是否为垃圾发送者
     */
    public boolean isSpammer() {
        // 计算未回复的接收方数量 l
        int l = sentTo.size() - (int) sentTo.stream().filter(receivedFrom::contains).count();

        // 计算发送与接收消息数量差值 m
        int m = sendCount.values().stream().mapToInt(Integer::intValue).sum() -
                receiveCount.values().stream().mapToInt(Integer::intValue).sum();

        // 判断是否满足垃圾发送者规则 1 和规则 2
        if (l > 5 || m > 10) {
            return true;
        }

        // 判断是否满足垃圾发送者规则 3
        for (int id : sentTo) {
            if (sendCount.get(id) - receiveCount.getOrDefault(id, 0) > 5) {
                return true;
            }
        }

        return false; // 如果不满足任何规则,则不是垃圾发送者
    }

    /**
     * 获取未回复的接收方数量 l
     *
     * @return 未回复的接收方数量
     */
    public int getL() {
        return sentTo.size() - (int) sentTo.stream().filter(receivedFrom::contains).count();
    }

    /**
     * 获取发送与接收消息数量差值 m
     *
     * @return 发送与接收消息数量差值
     */
    public int getM() {
        return sendCount.values().stream().mapToInt(Integer::intValue).sum() -
                receiveCount.values().stream().mapToInt(Integer::intValue).sum();
    }
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C++解法

给定一个消息记录的列表,记录的形式为 (sender, receiver),表示某个发送者向某个接收者发送了一条消息。
给定一个目标用户 ID targetId,需要分析该用户是否为垃圾发送者,并输出以下三个结果:
是否为垃圾发送者(true 或 false)。
L:目标用户发送的接收者中未回复的接收者数量。
M:目标用户的总发送消息数量减去总接收消息数量的差值。
垃圾发送者判定规则

满足以下任意一条规则,即判定为垃圾发送者:
L > 5,即未回复的接收者数量超过 5。
M > 10,即发送和接收的消息数量差值超过 10。
对任意接收者,如果发送消息数量比接收到的消息数量多 5 条以上,则判定为垃圾发送者。
算法设计

遍历消息记录,统计目标用户的发送和接收情况:
使用 unordered_set 分别记录目标用户发送消息的接收者和接收消息的发送者。
使用 unordered_map 记录每个接收者收到的消息数量和每个发送者发送给目标用户的消息数量。
累计目标用户的总发送消息数量和接收消息数量。
计算 L 和 M:
L 为发送集合中未被接收集合覆盖的部分。
M 为总发送消息数量减去总接收消息数量。
判断是否满足垃圾发送者条件

#include 
#include 
#include 
#include 
using namespace std;

int main() {
    int entryCount;
    cin >> entryCount; // 输入记录的数量

    // 存储所有消息记录
    vector<pair<int, int>> records(entryCount);
    for (int i = 0; i < entryCount; i++) {
        int sender, receiver;
        cin >> sender >> receiver; // 输入每条记录的发送者和接收者
        records[i] = {sender, receiver};
    }

    int targetId;
    cin >> targetId; // 输入目标用户 ID

    // 定义集合和映射,用于统计发送和接收情况
    unordered_set<int> sentTo;            // 目标用户发送消息的接收者集合
    unordered_set<int> receivedFrom;     // 目标用户接收消息的发送者集合
    unordered_map<int, int> sentCount;   // 每个接收者收到的消息数量
    unordered_map<int, int> receivedCount; // 每个发送者发送给目标用户的消息数量
    int sentMessages = 0;                // 目标用户的总发送消息数量
    int receivedMessages = 0;            // 目标用户的总接收消息数量

    // 遍历所有记录,统计目标用户的发送和接收信息
    for (auto& record : records) {
        if (record.first == targetId) { // 如果目标用户是发送者
            sentTo.insert(record.second); // 添加接收者到发送集合
            sentMessages++; // 增加总发送消息数量
            sentCount[record.second]++; // 更新该接收者收到的消息数量
        } else if (record.second == targetId) { // 如果目标用户是接收者
            receivedMessages++; // 增加总接收消息数量
            receivedFrom.insert(record.first); // 添加发送者到接收集合
            receivedCount[record.first]++; // 更新该发送者发送的消息数量
        }
    }

    // 计算未回复的接收者数量 L
    for (auto& id : receivedFrom) {
        sentTo.erase(id); // 移除接收集合中存在的接收者
    }
    int L = sentTo.size(); // 未被移除的接收者数量即为未回复的接收者数量

    // 计算发送和接收消息数量差值 M
    int M = sentMessages - receivedMessages;

    // 判定是否为垃圾发送者
    bool isSpam = (L > 5) || (M > 10); // 检查规则 1 和规则 2
    for (auto& [receiver, count] : sentCount) {
        // 检查规则 3:单个接收者发送与接收消息数量差值是否超过 5
        if (receivedCount.count(receiver) && (count - receivedCount[receiver] > 5)) {
            isSpam = true;
            break;
        }
    }

    // 输出结果
    cout << boolalpha << isSpam << " " << L << " " << M << endl;

    return 0;
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

给定若干条消息日志,每条日志记录了消息的发送者和接收者 (sender, receiver)。
需要分析一个指定的用户 targetId 的消息行为,判断其是否为垃圾短信发送者。
判断规则:
目标用户的独立接收者数量 L > 5。
目标用户发送的总消息数量减去接收到的总消息数量 M > 10。
目标用户对某个接收者发送的消息数量比从该接收者接收到的消息数量多出 5 条。
输入输出格式

输入:
第一行是消息日志的条目数 n。
接下来 n 行,每行包含一条消息日志,格式为 sender receiver。
最后一行是目标用户的 ID targetId。
输出:
格式为 “isSpammer L M”,其中:
isSpammer 是 true 或 false,表示目标用户是否为垃圾短信发送者;
L 是独立接收者数量;
M 是总发送消息数量与接收消息数量的差值。
算法设计

使用两个哈希表统计消息记录:
outgoingMessages:记录每个用户的发送消息详情,包括总发送量和独立接收者集合。
incomingMessages:记录每个用户接收消息的总数。
统计目标用户的 L 和 M 值:
L 为目标用户的独立接收者数量。
M 为目标用户的发送消息数量减去接收消息数量。
检查垃圾发送者的规则,逐条判断是否满足

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let inputs = [];
let totalRecords;

rl.on("line", (line) => {
  inputs.push(line);

  // 读取第一行消息记录总数
  if (inputs.length === 1) {
    totalRecords = parseInt(inputs[0], 10);
  }

  // 当输入完整时处理数据
  if (inputs.length === totalRecords + 2) {
    inputs.shift(); // 移除第一行记录(消息总数)
    const targetId = inputs.pop(); // 获取最后一行作为目标用户 ID
    const messageLogs = inputs.map((line) => line.split(" ").map(Number)); // 将日志解析为数组

    // 调用函数分析目标用户的消息行为
    console.log(analyzeMessages(parseInt(targetId, 10), messageLogs));
    inputs = []; // 重置输入数据
  }
});

/**
 * 判断目标ID是否为垃圾短信发送者
 * @param {number} targetId 目标的ID
 * @param {Array>} messageLogs 消息日志,格式为 [[sender, receiver], ...]
 * @returns {string} 返回是否为垃圾短信发送者以及L和M值
 */
function analyzeMessages(targetId, messageLogs) {
  // 定义哈希表用于存储发送和接收消息的数据
  const outgoingMessages = {}; // 记录用户的发送数据
  const incomingMessages = {}; // 记录用户的接收数据

  // 遍历消息日志,统计发送和接收数据
  messageLogs.forEach(([sender, receiver]) => {
    // 初始化发送数据
    if (!outgoingMessages[sender]) {
      outgoingMessages[sender] = { totalSent: 0, uniqueReceivers: new Set() };
    }

    // 初始化接收数据
    if (!incomingMessages[receiver]) {
      incomingMessages[receiver] = 0;
    }

    // 更新发送数据
    outgoingMessages[sender].totalSent++;
    outgoingMessages[sender].uniqueReceivers.add(receiver);

    // 更新接收数据
    incomingMessages[receiver]++;
  });

  // 获取目标用户的统计信息
  const totalSent = outgoingMessages[targetId]?.totalSent || 0; // 目标用户的总发送消息数量
  const totalReceived = incomingMessages[targetId] || 0; // 目标用户的总接收消息数量
  const uniqueReceivers = outgoingMessages[targetId]?.uniqueReceivers.size || 0; // 目标用户的独立接收者数量

  // 计算 L 和 M
  const L = uniqueReceivers; // 独立接收者数量
  const M = totalSent - totalReceived; // 发送与接收的差值

  // 判断垃圾发送者规则
  let isSpammer = L > 5 || M > 10; // 规则 1 和规则 2
  if (!isSpammer) {
    // 规则 3:检查是否有接收者与目标用户的发送接收差值超过 5
    for (let receiver of outgoingMessages[targetId]?.uniqueReceivers || []) {
      const sentToReceiver = outgoingMessages[targetId].totalSent;
      const receivedFromReceiver = incomingMessages[receiver] || 0;
      if (sentToReceiver - receivedFromReceiver > 5) {
        isSpammer = true;
        break;
      }
    }
  }

  // 返回结果,格式为 "isSpammer L M"
  return `${isSpammer} ${L} ${M}`;
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/145058799"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!