【OD机试题笔记】发广播

题目描述

某地有N个广播站,站点之间有些有连接,有些没有。有连接的站点在接受到广播后会互相发送。

给定一个N*N的二维数组matrix,数组的元素都是字符’0’或者’1’。

matrix[i][j] = ‘1’, 代表i和j站点之间有连接,

matrix[i][j] = ‘0’, 代表没连接,

现在要发一条广播,问初始最少给几个广播站发送,才能保证所有的广播站都收到消息。

输入描述
从stdin输入,共一行数据,表示二维数组的各行,用逗号分隔行。保证每行字符串所含的字符数一样的。

比如:110,110,001。

输出描述
返回初始最少需要发送广播站个数

用例
输入
110,110,001
输出
2
说明
站点1和站点2直接有连接,站点3和其他的都没连接,所以开始至少需要给两个站点发送广播。

输入
100,010,001
输出
3
说明
3台服务器互不连接,所以需要分别广播这3台服务器。
输入
11,11

思路

问题本质转化

  • 每个广播站是一个 节点(编号 0 到 N-1,N 是广播站数量);
  • matrix[i][j] = '1' 表示节点 i 和 j 之间有 无向边(双向连通);
  • “初始最少发送广播的个数” = 无向图中 连通分量的数量(每个连通分量只需给一个节点发广播,整个分量都会通过连接传播到所有节点)。

两种核心解法(并查集 / DFS)

解法一:并查集(推荐,效率高、代码简洁)

并查集的核心作用是 动态维护节点的连通关系,并快速查询连通分量数量。

并查集解题步骤
  1. 初始化
    • 每个节点的父节点初始化为自身(parent[i] = i);
    • count 记录连通分量初始数量(等于节点总数 N)。
  2. 遍历所有边
    • 遍历二维数组 matrix,对于每个 i < j(避免重复处理无向边,因为 matrix[i][j]matrix[j][i] 是同一连接):
      • matrix[i][j] == '1',说明 i 和 j 连通,执行 合并操作
      • 合并前先查询 i 和 j 的根节点:若根节点不同,说明两个连通分量可以合并,count--(连通分量数量减少 1)。
  3. 返回结果:最终 count 就是最少需要发送广播的个数。
并查集代码实现
function solution() {
   
   
   const rows = readline().split(',');
   const n = rows.length; // 广播站数量

    // 并查集初始化:parent[i] = i
    const parent = new Array(n);
    for (let i = 0; i < n; i++) {
   
   
        parent[i] = i;
    }

    // 查找根节点(带路径压缩)
    const find = (x) => {
   
   
        if (parent[x] !== x) {
   
   
            parent[x] = find(parent[x]); // 路径压缩,加速后续查询
        }
        return parent[x];
    };

    // 合并两个集合(按秩合并)
    const 
### 华为 OD 试题及解答 #### Java 题目解析 在华为 OD 考中,Java 是一种常见的编程语言。以下是一个关于二进制位操作的经典题目及其解决方案。 给定一个整数 `num`,计算其二进制表示中有多少个 `1` 的方法可以通过逐位检查实现[^2]。 以下是具体的代码示例: ```java import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int num = in.nextInt(); // 输入数字 int count = 0; // 计数器初始化 for (int i = 0; i < 32; i++) { // 假设输入的是标准的 32 位整数 if ((num & 1) == 1) { // 如果当前最低位是 1,则增加计数 count++; } num = num >>> 1; // 将数字无符号右移一位 } System.out.println(count); // 输出最终的结果 } } ``` 此程序的核心在于利用按位与运算符 (`&`) 和无符号右移运算符 (`>>>`) 来逐步提取并统计二进制中的每一位是否为 `1`。 --- #### 字符串处理题目解析 另一个常见问题是字符串的操作,比如将字符串中的每个单词首字母大写化[^3]。下面是一段 Python 实现的例子: ```python while True: try: words = input().split() # 获取用户输入并分割成列表 result = [] for word in words: if len(word) > 0: # 确保单词长度大于零 capitalized_word = f"{word[0].upper()}{word[1:]}" result.append(capitalized_word) print(" ".join(result)) # 打印结果 except Exception as e: break # 捕获异常后退出循环 ``` 该脚本通过遍历每一个单词,并将其第一个字符转为大写字母来完成任务。 --- #### 准备建议 为了更好地应对华为 OD 试,可以采取如下策略: - **熟悉常用算法**:掌握基本的数据结构(数组、链表、堆栈等)以及经典算法(排序、查找等),这些知识点经常会在实际测试中被考察到。 - **多练习编码能力**:针对不同类型的题目进行专项训练,尤其是时间复杂度优化方面的技巧学习。 - **理解业务场景需求**:部分试题可能结合具体应用场景设计,因此除了技术层面外还需要考虑逻辑思维的应用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值