2022第十三届蓝桥杯B组C++省赛H题 扫雷
【问题描述】
小明最近迷上了一款名为《扫雷》的游戏。其中有一个关卡的任务如下, 在一个二维平面上放置着 n 个炸雷,第 i 个炸雷 (xi, yi, ri) 表示在坐标 (xi, yi) 处 存在一个炸雷,它的爆炸范围是以半径为 ri 的一个圆。 为了顺利通过这片土地,需要玩家进行排雷。玩家可以发射 m 个排雷火 箭,小明已经规划好了每个排雷火箭的发射方向,第 j 个排雷火箭 (xj, yj, rj) 表 示这个排雷火箭将会在 (xj, yj) 处爆炸,它的爆炸范围是以半径为 rj 的一个圆, 在其爆炸范围内的炸雷会被引爆。同时,当炸雷被引爆时,在其爆炸范围内的 炸雷也会被引爆。现在小明想知道他这次共引爆了几颗炸雷? 你可以把炸雷和排雷火箭都视为平面上的一个点。一个点处可以存在多个 炸雷和排雷火箭。当炸雷位于爆炸范围的边界上时也会被引爆。
【输入格式】
输入的第一行包含两个整数 n、m 接下来的 n 行,每行三个整数 xi , yi ,ri,表示一个炸雷的信息。 再接下来的 m 行,每行三个整数 xj , yj ,rj,表示一个排雷火箭的信息。
【输出格式】
输出一个整数表示答案。
【样例输入】
2 1
2 2 4
4 4 2
0 0 5
【样例输出】
2
【样例说明】
示例图如下,排雷火箭 1 覆盖了炸雷 1,所以炸雷 1 被排除;炸雷 1 又覆 盖了炸雷 2,所以炸雷 2 也被排除。
【评测用例规模与约定】
对于 40% 的评测用例:0 ≤ x, y ≤ 109 , 0 ≤ n, m ≤ 103 , 1 ≤ r ≤ 10.
对于 100% 的评测用例:0 ≤ x, y ≤ 109 , 0 ≤ n, m ≤ 5 × 104 , 1 ≤ r ≤ 10.
当时用dfs做的,最后一分钟还在挣扎在找错误TuT....
昨天看到的:“直接两重循环建边+dfs搜索的,会炸(因为建边是两重循环,过不叫第二个5e4的样例)”
一个只过了40%的代码(...):
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=50100; 4 //炸雷的坐标和半径 5 int x_pos[maxn]; 6 int y_pos[maxn]; 7 int radius[maxn]; 8 bool vis[maxn];//标记是否爆炸 9 10 struct point 11 { 12 int x,y,r; 13 //将结构体放入 map 中作为键,需要自己写一个 operator 来排序 14 bool operator<(const point &p)const 15 { 16 if(x==p.x) 17 { 18 if(y==p.y) 19 {return r<p.r;} 20 return y<p.y; 21 } 22 return x<p.x; 23 } 24 }; 25 26 map<point,int>all; 27 28 double getdis(int x1,int y1,int x2,int y2) 29 { 30 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 31 } 32 33 int bfs(point begin,int n) 34 { 35 long long int cnt=0; 36 queue<point>q; 37 q.push(begin); 38 while(!q.empty()) 39 { 40 point cur=q.front(); 41 q.pop(); 42 //遍历排雷火箭所在的最小正方形,找到其涉及爆炸的雷 43 for(register int i=cur.x-cur.r;i<=cur.x+cur.r;i++) 44 { 45 for(register int j=cur.y-cur.r;j<=cur.y+cur.r;j++) 46 { 47 if(getdis(i,j,cur.x,cur.y)>cur.r) 48 continue; 49 point temp; 50 temp.x=i; 51 temp.y=j; 52 for(register int k=0;k<n;k++) 53 { 54 if(!vis[k]&&x_pos[k]==temp.x&&y_pos[k]==temp.y) 55 { 56 temp.r=radius[k]; 57 q.push(temp); 58 cnt++; 59 vis[k]=true;//标记已炸 60 all[temp]--; 61 } 62 } 63 } 64 } 65 } 66 return cnt; 67 } 68 69 int main() 70 { 71 int n,m,cnt=0; 72 cin>>n>>m; 73 for(register int i=0;i<n;i++) 74 { 75 cin>>x_pos[i]>>y_pos[i]>>radius[i]; 76 vis[i]=false;//初始化全部未炸 77 } 78 for(register int i=0;i<m;i++) 79 { 80 point p; 81 cin>>p.x>>p.y>>p.r; 82 cnt+=bfs(p,n); 83 } 84 cout<<cnt; 85 return 0; 86 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)