扫雷真题dfs(2022蓝桥杯)

小明最近迷上了一款名为《扫雷》的游戏。

其中有一个关卡的任务如下:

在一个二维平面上放置着 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 也被排除。

评测用例规模与约定

 

 

 22年蓝桥这题20分,20*0.4==8分,用dfs捞分虽然不能过全部样例,但是也不错了。

 题目要求用火箭去找半径范围内能引爆的炸雷数量,同时炸雷范围内的爆炸也能引起其他炸雷的爆炸 
思路: 将每个火箭去寻找与所有的炸雷比较,先判断该炸雷是否用过,再判断是否在范围内,同时若炸雷能引起其他炸雷爆炸,
再将该炸雷与其他炸雷比较,本题不需要回溯,炸雷炸过了,不需要复原 

#include <iostream>
#include<algorithm>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int W = 50010;//看数据量范围,题目要求扫雷和炸雷都能范围是0--10^4,所以定义常量W稍微大于50000一些 
struct node
{
 int x,y,r,n;//定义结构体 ,x,y存储位置,r半径,n对应编号(第几个) 
};
ll i,j,a,n,m,b,r,N=0; 
ll v[W];
node arr1[W],arr2[W]; //arr1存储炸雷,arr2存储火箭,
//题目要求用火箭去找半径范围内能引爆的炸雷数量,同时炸雷范围内的爆炸也能引起其他炸雷的爆炸 
//思路: 将每个火箭去寻找与所有的炸雷比较,先判断该炸雷是否用过,再判断是否在范围内,同时若炸雷能引起其他炸雷爆炸,
//再将该炸雷与其他炸雷比较,本题不需要回溯,炸雷炸过了,不需要复原 

bool compare(node x,node y)//比较炸雷y是否在火箭x范围内或者比较 炸雷y是否在炸雷x范围内
{//通过直角三角形勾股定理计算两点直线距离,再与x的半径比较大小,若小于等于则在范围内 返回true、否则false 
 int a=abs((x.x-y.x));
 int b=abs((x.y-y.y));
 return sqrt(a*a+b*b)<=x.r;
 
}
void dfs(node a)
{
 for(int i=0;i<n;i++)//将当前火箭a与每个炸雷依次比较
 {
  if(v[arr1[i].n]==0)//若炸雷未用过,为0,v[n]根据炸雷编号判断,
  {
   if(compare(a,arr1[i]))//若在范围内返回true 
   {
   	v[arr1[i].n]=1;//将该编号标记为已经用过,本题不需要回溯 
   	N++;
   	dfs(arr1[i]);//炸雷范围内的爆炸也能引起其他炸雷的爆炸,递归 
   }
  }
 }
 
}
int main()
{

 cin>>n>>m;//输入炸雷数n,火箭数m 
 memset(v,0,sizeof(v)); 
 for(int i=0;i<n;i++) 
 {//炸雷位置,半径,编号 
 scanf("%d%d%d",&a,&b,&r);
 arr1[i].x=a;
 arr1[i].y=b;
 arr1[i].r=r;
 arr1[i].n=i; 
 }
 for(int i=0;i<m;i++) 
 {//火箭位置,半径,编号 
 scanf("%d%d%d",&a,&b,&r);
 arr2[i].x=a;
 arr2[i].y=b;
 arr2[i].r=r; 
 arr2[i].n=i;
 }
 for(int i=0;i<m;i++)//将每个火箭依次发射 
 dfs(arr2[i]);
 
 cout<<N<<endl;//输出引爆的炸雷数量 
 return 0;
 
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值