当前位置:首页 > 蓝桥杯 > 2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解

2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解

3个月前 (06-10)

2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解 蓝桥杯  BFS算法 第1张

一、题目解读

2022年蓝桥杯省赛B组机器人塔(洛谷P8785)是一道经典的算法题目,要求处理在一个二维平面上布置的炸雷与排雷火箭。炸雷具有爆炸半径,当排雷火箭引爆后,会触发周围范围内未被引爆的炸雷,形成连锁反应。题目需要计算最终引爆的炸雷数量,考验对广度优先搜索BFS)与距离计算的灵活运用,以及对多炸雷位置叠加处理的能力。

二、解题思路

核心思路采用BFS遍历排雷火箭,通过计算爆炸范围动态引爆周围炸雷。具体步骤为:

1. 使用unordered_map存储每个位置的炸雷列表,允许同一坐标存在多个炸雷;

2. 通过BFS依次处理排雷火箭,计算其爆炸范围内的所有炸雷坐标;

3. 若炸雷未被引爆,则标记并加入队列,形成连锁引爆;

4. 统计引爆次数,最终输出结果。

三、解题步骤

1. 数据读取:输入炸雷数量n与排雷火箭数量m,存储炸雷坐标(x, y, r)及排雷火箭位置;

2. 初始化结构:建立mines哈希表记录炸雷分布,q队列存储待引爆的火箭/炸雷;

3. BFS引爆处理:

    取出队列头部元素,计算爆炸范围矩形区域;

    遍历区域内所有坐标,判断炸雷是否存在且未引爆;

    若符合条件,标记炸雷引爆并加入队列,继续触发后续引爆;

4. 统计引爆数量:通过队列循环次数或标记变量计算最终结果。

四、代码及注释

#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <unordered_map>
using namespace std;

struct Point {
    int x, y, r;   // 坐标(x, y)与半径r
    bool exploded = false;  // 是否已引爆标记
};

// 计算两点间距离平方
int distance2(int x1, int y1, int x2, int y2) {
    int dx = x1 - x2;
    int dy = y1 - y2;
    return dx*dx + dy*dy;   // 优化平方计算避免开方
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);   // 加速输入输出

    int n, m;
    cin >> n >> m;   // 读取炸雷与排雷火箭数量

    // 使用map存储每个位置的炸雷列表,相同位置可能有多个炸雷
    unordered_map<int, unordered_map<int, vector<Point>>> mines;
    vector<Point> mine_list;

    // 读取炸雷数据
    for (int i = 0; i < n; ++i) {
        int x, y, r;
        cin >> x >> y >> r;
        mine_list.push_back({x, y, r, false});
        mines[x][y].push_back({x, y, r, false});
    }

    queue<Point> q;   // 引爆队列
    int count = 0;   // 引爆次数

    // 处理排雷火箭
    for (int i = 0; i < m; ++i) {
        int x, y, r;
        cin >> x >> y >> r;
        q.push({x, y, r, false});
    }

    // BFS处理引爆过程
    while (!q.empty()) {
        Point current = q.front();
        q.pop();
        
        // 检查周围可能被引爆的炸雷
        int min_x = current.x - current.r;
        int max_x = current.x + current.r;
        int min_y = current.y - current.r;
        int max_y = current.y + current.r;
        
        for (int x = min_x; x <= max_x; ++x) {
            for (int y = min_y; y <= max_y; ++y) {
                // 检查距离是否在爆炸范围内
                if (distance2(current.x, current.y, x, y) > current.r * current.r) 
                    continue;
                
                // 检查该位置是否有炸雷
                if (mines.find(x)!= mines.end() && mines[x].find(y)!= mines[x].end()) {
                    for (auto& mine : mines[x][y]) {
                        if (!mine.exploded) {
                            mine.exploded = true;
                            count++;   // 统计引爆次数
                            q.push(mine);   // 加入队列触发后续引爆
                        }
                    }
                }
            }
        }
    }
    // 输出最终引爆数量
    cout << count << endl;
}

五、总结

该解法巧妙利用unordered_map处理位置重叠的炸雷,结合BFS实现高效引爆传播。关键点在于:

1. 爆炸范围计算采用距离平方避免耗时开方;

2. 通过队列实现递归式引爆,避免手动递归溢出风险;

3. 标记引爆状态避免重复计算。

在实际算法设计中,需注意数据结构的选择与边界条件的严谨处理,以提升效率与准确性。


原创内容 转载请注明出处

分享给朋友:

相关文章

牛客13279题解:基于广度优先搜索(BFS)计算树高度的算法优化与代码实现

牛客13279题解:基于广度优先搜索(BFS)计算树高度的算法优化与代码实现

一、题目解读牛客13279题要求计算给定树的高度。树由n个节点组成,通过n-1条边连接,形成一棵有根树。题目核心在于高效求解树的高度,即从根节点到最深叶子节点的最长路径长度。需要理解树的结构特点,选择...

洛谷P1747题解:遍历最短路径(BFS算法优化)

洛谷P1747题解:遍历最短路径(BFS算法优化)

一、题目解读洛谷P1747题目要求模拟中国象棋中“马”的移动规则,计算从任意起点到终点所需的最小步数。题目中马的移动方式包括传统的“日”字步(8种方向)及特殊“田”字步(4种方向),需在限定范围内寻找...

2025蓝桥杯省赛A组地雷阵题解:几何转化与区间合并算法详解

2025蓝桥杯省赛A组地雷阵题解:几何转化与区间合并算法详解

一、题目解读2025年蓝桥杯省赛A组地雷阵题目(洛谷12144)要求计算在平面直角坐标系第一象限中,给定n个地雷的位置坐标和触发半径,从原点出发随机选择一个方向行走,不触发地雷的通关概率。题目将游戏问...

牛客25438题解析:机器人移动可达点数量的BFS算法优化

牛客25438题解析:机器人移动可达点数量的BFS算法优化

一、题目解读牛客25438题要求计算在一个m行n列的网格中,从原点(0,0)出发,每次只能向上、下、左、右移动一步,且移动后的坐标各位数字之和不超过k的情况下,可达点的总数。题目考察对BFS(广度优先...

(2017蓝桥杯省A)洛谷P8650题解:递归解析正则表达式并求解最大长度

(2017蓝桥杯省A)洛谷P8650题解:递归解析正则表达式并求解最大长度

一、题目解读洛谷P8650题要求解析由‘x’、‘|’和括号组成的表达式,计算并输出其最大长度。题目核心在于处理嵌套括号与‘|’分隔的项。二、解题思路使用递归策略:1. 解析因子:识别单个‘x’或括号表...

(2023蓝桥杯国A)洛谷P10422题解:基于状态压缩DP与优先队列的图论优化算法解析

(2023蓝桥杯国A)洛谷P10422题解:基于状态压缩DP与优先队列的图论优化算法解析

一、题目解读洛谷P10422题描述了一个包含N个节点的图,每个节点可能存在怪物,玩家需从起点出发,击杀所有怪物并抵达终点,同时需考虑血量消耗与时间限制。题目要求计算最小耗时,若无法完成则输出-1。核心...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。