1 条题解
-
0
📝 题目大意
给定一个 的网格,包含空地
.、墙#和威力为 的炸弹。所有炸弹同时爆炸,将曼哈顿距离不超过其威力的所有墙变为空地(炸弹之间互不影响),炸弹自身也会消失。输出爆炸后的最终盘面。💡 解题思路
-
题目分析:,数据规模极小, 的暴力枚举完全可行。关键点在于"炸弹同时爆炸"且"炸弹之间互不影响"——炸弹不会炸毁其他炸弹,只有墙
#会被炸掉。 -
算法推导:
- 遍历棋盘每个格子,当遇到数字字符(炸弹)时:
- 记录炸弹威力值
bom = 字符 - '0'(第 26 行) - 将炸弹自身位置设为
.(第 27 行),满足"炸弹爆炸后自身消失" - 再遍历整个棋盘,若当前格子是
#且与炸弹的曼哈顿距离 ,则将其改为.(第 32-35 行)
- 记录炸弹威力值
- 由于炸弹只炸
#而不炸数字格子(第 32 行的continue跳过了所有非#格子),炸弹之间的互不影响自然得到保证。 - 输出最终棋盘即可。
- 遍历棋盘每个格子,当遇到数字字符(炸弹)时:
-
边界与细节:
- 曼哈顿距离公式:
- 输入只有
1~9,不会出现0威力炸弹。 - 样例 2 中无炸弹,输出即输入,无需特殊处理。
- 注意:若先处理炸弹 A 将某些
#变为.,再处理炸弹 B 时这些格子已不是#,不会被重复处理,这恰好符合"同时爆炸"的语义——每个墙只需被摧毁一次。
⏱️ 复杂度分析
- 时间复杂度:——最坏情况下每个格子都是炸弹,每个炸弹都遍历整个棋盘。 时最多约 次运算,完全足够。
- 空间复杂度:——仅需存储棋盘。
💻 标准代码 (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
- 上传者