【蓝桥杯】水质检测

水质检测

题目描述

小明需要在一条 2 × n 2 \times n 2×n 的河床上铺设水质检测器。在他铺设之前,河床上已经存在一些检测器。如果两个检测器上下或者左右相邻,那么这两个检测器就是互相连通的。连通具有传递性,即如果 A A A 和 B B B 连通, B B B 和 C C C 连通,那么 A A A 和 C C C 也连通。现在他需要在河床上增加铺设一些检测器使得所有的检测器都互相连通。他想知道最少需要增加铺设多少个检测器?

输入格式

输入共两行,表示一个 2 × n 2 \times n 2×n 的河床。

每行一个长度为 n n n 的字符串,仅包含 #.,其中 # 表示已经存在的检测器,. 表示空白。

输出格式

输出共 1 1 1 行,一个整数表示答案。

输入输出样例 #1
输入 #1
shell 复制代码
##.....#
#.#.#...
输出 #1
复制代码
5
说明/提示
样例说明

其中一种方案:

shell 复制代码
###....#
#.######

增加了 5 个检测器。

评测用例规模与约定

对于 100 % 100\% 100% 的评测用例,保证 n ≤ 1000000 n \leq 1000000 n≤1000000。

P12135 [蓝桥杯 2025 省 B] 水质检测

【思路分析】

状态表示

f[i][j] 代表第 i 行(i 取值为 0 或 1,分别对应第一行和第二行)使得到第 j 个位置的所有检测器连通的最小安装机器数量。

状态计算

状态转移方程

每个位置的状态可以从同一行的上一个位置或者另一行的上一个位置转移过来,因此状态转移方程如下:

  • f[0][j] = Math.min(f[0][j - 1] + a[0][j], f[1][j - 1] + a[1][j] + a[0][j])
  • f[1][j] = Math.min(f[1][j - 1] + a[1][j], f[0][j - 1] + a[1][j] + a[0][j])
java 复制代码
import java.io.*;
import java.util.*;
public class Main {
    // 定义数组的最大长度,考虑到 n 的最大值为 1000000,这里设置为 1000010
    static final int N = 1000010;
    // 是否遇见了第一个机器的标志
    static boolean isFirstMachine;
    // f 数组用于存储动态规划的状态
    static int[][] f = new int[2][N];
    // a 数组用于预处理每个位置是否需要新增检测器,需要为 1,不需要为 0
    static int[][] a = new int[2][N];
    // 最后一个机器的位置
    static int lastMachine = 0;

    public static void main(String[] args) throws Exception {
        // 使用 BufferedReader 读取输入,提高读取效率
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str1 = br.readLine();
        String str2 = br.readLine();
        // 获取输入字符串的长度,即河床的列数
        int n = str1.length();

        // 预处理所有位置是否需要新增一个机器
        for(int i = 0; i < n; i++) {
            // 第一行的第 i 个位置如果是机器,第一行的下一个位置就不需要填充机器
            if(str1.charAt(i) == '#') {
                a[0][i + 1] = 0;
                // 更新最后一个机器的位置
                lastMachine = i + 1;
            } else if(str1.charAt(i) == '.') {
                a[0][i + 1] = 1;
            }
            // 第二行的第 i 个位置如果是机器,第二行的下一个位置就不需要填充机器
            if(str2.charAt(i) == '#') {
                a[1][i + 1] = 0;
                // 更新最后一个机器的位置
                lastMachine = i + 1;
            } else if(str2.charAt(i) == '.') {
                a[1][i + 1] = 1;
            }
        }

        // 状态计算
        for(int i = 1; i <= lastMachine; i++) {
            // 找到第一个机器的位置
            if(isFirstMachine == false && (a[0][i] == 0 || a[1][i] == 0)) {
                isFirstMachine = true;
            }
            if(isFirstMachine) {
                // 状态转移方程,计算第 0 行第 i 个位置的最小安装机器数量
                f[0][i] = Math.min(f[0][i - 1] + a[0][i], f[1][i - 1] + a[1][i] + a[0][i]);
                // 状态转移方程,计算第 1 行第 i 个位置的最小安装机器数量
                f[1][i] = Math.min(f[1][i - 1] + a[1][i], f[0][i - 1] + a[1][i] + a[0][i]);
            }
        }
        // 输出结果,取第 0 行和第 1 行最后一个机器位置的最小安装机器数量
        System.out.println(Math.min(f[0][lastMachine], f[1][lastMachine]));
        // 关闭 BufferedReader
        br.close();
    } 
}
相关推荐
前端小超超3 天前
capacitor配置ios应用图标不同尺寸
ios·蓝桥杯·cocoa
汉克老师5 天前
第十四届蓝桥杯青少组C++选拔赛[2023.1.15]第二部分编程题(4 、移动石子)
c++·算法·蓝桥杯·蓝桥杯c++·c++蓝桥杯
旭意5 天前
C++微基础蓝桥杯之旅9.9-9.12
c++·算法·蓝桥杯
HAH-HAH6 天前
【蓝桥杯 2024 国 Java A】粉刷匠小蓝
c++·学习·数学·算法·职场和发展·蓝桥杯·组合数学
汉克老师6 天前
第十四届蓝桥杯青少组C++选拔赛[2023.1.15]第二部分编程题(2 、寻宝石)
c++·蓝桥杯·蓝桥杯c++·c++蓝桥杯·蓝桥杯选拔赛
汉克老师7 天前
第十四届蓝桥杯青少组C++选拔赛[2023.2.12]第二部分编程题(5、机甲战士)
c++·算法·蓝桥杯·01背包·蓝桥杯c++·c++蓝桥杯
Jared_devin7 天前
二叉树算法题—— [蓝桥杯 2019 省 AB] 完全二叉树的权值
数据结构·c++·算法·职场和发展·蓝桥杯
aaaweiaaaaaa9 天前
c++基础学习(学习蓝桥杯 ros2有C基础可看)
c++·学习·蓝桥杯·lambda·ros2·智能指针·c++类
汉克老师9 天前
第十四届蓝桥杯青少组C++选拔赛[2023.2.12]第二部分编程题(4、最大空白区)
c++·算法·蓝桥杯·蓝桥杯c++·c++蓝桥杯
scx2013100410 天前
P13929 [蓝桥杯 2022 省 Java B] 山 题解
c++·算法·蓝桥杯·洛谷