1 条题解

  • 0
    @ 2026-6-19 10:30:30

    📝 题目大意

    给定一个 R×CR \times C 的网格,包含空地 .、墙 # 和威力为 191\sim9 的炸弹。所有炸弹同时爆炸,将曼哈顿距离不超过其威力的所有墙变为空地(炸弹之间互不影响),炸弹自身也会消失。输出爆炸后的最终盘面。

    💡 解题思路

    1. 题目分析R,C20R, C \le 20,数据规模极小,O(R2C2)O(R^2C^2) 的暴力枚举完全可行。关键点在于"炸弹同时爆炸"且"炸弹之间互不影响"——炸弹不会炸毁其他炸弹,只有墙 # 会被炸掉。

    2. 算法推导

      • 遍历棋盘每个格子,当遇到数字字符(炸弹)时:
        • 记录炸弹威力值 bom = 字符 - '0'(第 26 行)
        • 将炸弹自身位置设为 .(第 27 行),满足"炸弹爆炸后自身消失"
        • 再遍历整个棋盘,若当前格子是 # 且与炸弹的曼哈顿距离 ki+ljbom|k-i| + |l-j| \le bom,则将其改为 .(第 32-35 行)
      • 由于炸弹只炸 # 而不炸数字格子(第 32 行的 continue 跳过了所有非 # 格子),炸弹之间的互不影响自然得到保证。
      • 输出最终棋盘即可。
    3. 边界与细节

      • 曼哈顿距离公式:dist=x1x2+y1y2\text{dist} = |x_1 - x_2| + |y_1 - y_2|
      • 输入只有 1~9,不会出现 0 威力炸弹。
      • 样例 2 中无炸弹,输出即输入,无需特殊处理。
      • 注意:若先处理炸弹 A 将某些 # 变为 .,再处理炸弹 B 时这些格子已不是 #,不会被重复处理,这恰好符合"同时爆炸"的语义——每个墙只需被摧毁一次。

    ⏱️ 复杂度分析

    • 时间复杂度O(R2C2)O(R^2 C^2)——最坏情况下每个格子都是炸弹,每个炸弹都遍历整个棋盘。R,C20R,C \le 20 时最多约 1.6×1051.6 \times 10^5 次运算,完全足够。
    • 空间复杂度O(RC)O(RC)——仅需存储棋盘。

    💻 标准代码 (C++)

    #include <bits/stdc++.h>
    using namespace std;
    
    // 手动实现绝对值,等价于 std::abs
    int abss(int a)
    {
        if (a < 0) return a * -1;
        return a;
    }
    
    int main()
    {
        int r, c;
        cin >> r >> c;
        vector<string> b(r);          // 棋盘
    
        for (int i = 0; i < r; i++)
        {
            cin >> b[i];              // 读入每一行
        }
    
        for (int i = 0; i < r; i++)
        {
            for (int j = 0; j < c; j++)
            {
                // 遇到炸弹(数字字符)
                if (b[i][j] != '.' && b[i][j] != '#')
                {
                    int bom = b[i][j] - '0';    // 炸弹威力值
                    b[i][j] = '.';              // 炸弹自身爆炸后消失
    
                    // 遍历整个棋盘,摧毁范围内的墙
                    for (int k = 0; k < r; k++)
                    {
                        for (int l = 0; l < c; l++)
                        {
                            if (b[k][l] != '#') continue;   // 只炸墙,不炸空地和炸弹
    
                            int dist = abss(k - i) + abss(l - j);  // 曼哈顿距离
                            if (dist <= bom) b[k][l] = '.';        // 在爆炸范围内则摧毁
                        }
                    }
                }
            }
        }
    
        // 输出最终棋盘
        for (string s : b)
        {
            cout << s << endl;
        }
    }
    
    • 1

    信息

    ID
    695
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者