【蓝桥杯每日一题】扫雷 深度优先搜索

扫雷

知识点

2024-12-3 蓝桥杯每日一题 扫雷 dfs (bfs也是可行的)

题目大意

在一个二维平面上放置这N个炸雷,每个炸雷的信息有$(x_i,y_i,r_i) $,前两个是坐标信息,第三个是爆炸半径。然后会输入M个排雷火箭,同样的信息;排雷火箭会将范围内所有的炸雷炸掉,并且会引发一连串爆炸这就要根据爆炸半径来判断。

解题思路
  1. 要考虑怎么存储这个炸弹信息,并且还要方便遍历到。在题目中坐标范围是 1 0 9 10^9 109,肯定不能存到二维数组的平面坐标中。
  2. 使用 m a p < p a i r < i n t , i n t > , v e c t o r < i n t > > map,vector> map<pair<int,int>,vector<int>>,这样方便以O(1)的时间访问到当前位置,并且题目中明确表示同一个点可能会包含多个炸雷或火箭,(这一点一定看清楚),我就是这一点磕了一下;然后就是一定要使用map来定义,unordered_map我用的不行,应为这里使用到了pair。
  3. 最后就是递归遍历了,没输入一个火箭调用dfs;而且注意到 r 的的范围是很小的,我们就可以通过遍历当前位置为中心向四周扩展 r 长度的正方形,然后找到雷之后还要判断两点之间的距离是否在园内即可。
Accepted
#include 
using namespace std;

const int N = 5e4+10;
typedef long long ll;
typedef pair<int,int> pii;
int n,m,cnt;
map<pii,vector<int>> a;
// 两点之间的距离
ll dist(int x1,int y1,int x2,int y2) {
    return 1ll*(x1-x2)*(x1-x2) + 1ll*(y1-y2)*(y1-y2);
}

void dfs(int x,int y,int r) {
    for(int i = x-r;i <= x+r;i++) {
        for(int j = y-r;j <= y+r;j++) {
            if(a.count({i,j})) {
                int len = a[{i,j}].size();
                for(int k = 0;k < len;k++) {
                    int rr = a[{i,j}][k];
                    if(rr > 0 && dist(i,j,x,y) <= 1ll*r*r) {
                        a[{i,j}][k] = 0;
                        cnt++;
                        dfs(i,j,rr);
                    }
                }
            }
        }
    }
}

int main()
{
    int x,y,r;
    cin>>n>>m;
    for(int i = 1;i <= n;i++) {
        cin>>x>>y>>r;
        a[{x,y}].push_back(r);
    }
    while(m--) {
        cin>>x>>y>>r;
        dfs(x,y,r);
    }
    cout<<cnt;
    return 0;
}
备注

想要一起备赛的小伙伴可以看评论区添加讨论群!

你可能感兴趣的:(蓝桥杯,蓝桥杯,深度优先)