扫雷真题dfs(2022蓝桥杯)

Posted 教授先生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扫雷真题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;
 

蓝桥杯·寒假百校真题大联赛(大学B组)(第2期)《迷宫》(DFS版本)

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
const int w=50,h=30;

bool n[w][h];
struct DisNode

	int dis=w*h*2;
	int beforeW=-1;
	int beforeH=-1;
	char fromWith;//通过什么操作转移过来的。 
;
DisNode dis[w][h];
void mapIn()

	for(int i=0;i<h;i++)
	
		for(int j=0;j<w;j++)
		
			char cget=cin.get();
			while(cget!='0'&&cget!='1')
			
				cget=cin.get();
			
			n[j][i]=(cget=='1');
		
	

vector<char> getPath(DisNode p)

	vector<char> v;
	int w=p.beforeW;
	int h=p.beforeH;
	while(w!=-1&&h!=-1)
	
		v.push_back(p.fromWith);
		p=dis[w][h];
		w=p.beforeW;
		h=p.beforeH;
	
	reverse(v.begin(),v.end());
	return v;

bool normalData(int w,int h)

	if(w<0||h<0) return false;
	return true;

bool aBiggerThanB(DisNode a,DisNode b)//a>=b

	if(a.dis>b.dis) return true;
	else if(a.dis==b.dis)
	
		vector<char> pathA=getPath(a);
		vector<char> pathB=getPath(b);
		for(int i=0;i<pathA.size();i++)
		
			if(pathA[i]<pathB[i]) return false;
			else if(pathA[i]>pathB[i]) return true;
			else if(pathA[i]==pathB[i]) continue;
		
		return true;//如果一样大,也算是a>=b 
	
	else
	
		return false;
	

bool canMoveToNewState(int nowW ,int nowH,DisNode a,DisNode b,char action)//a 是old状态,b是要转移的状态(现态),其他参数是状态转移信息. 

	b.dis=b.dis+1;
	b.beforeH=nowH;
	b.beforeW=nowW;
	b.fromWith=action;
	if(aBiggerThanB(a,b))//如果转移后的状态满足转移条件
	
		return true;
	 
	else
	
		return false; 
	

bool tryMoveToNewState(int nowW,int nowH,int toW, int toH,char action)

	if(!normalData(toW,toH)) return false;
	if(toW<0||toH<0) return false;
	if(toW>w-1||toH>h-1) return false;
	if(n[toW][toH]) return false;	//目标位置是个墙壁无法转移 
	if(canMoveToNewState(nowW,nowH,dis[toW][toH],dis[nowW][nowH],action))
	
		dis[toW][toH].dis=dis[nowW][nowH].dis+1;
		dis[toW][toH].beforeH=nowH;
		dis[toW][toH].beforeW=nowW;
		dis[toW][toH].fromWith=action;
		return true;
	
	else
	
		return false;
	

void PrintOut()

	vector<char> c;
	DisNode d= dis[w-1][h-1];
	while(d.beforeH!=-1&&d.beforeW!=-1)
	
		c.push_back(d.fromWith);
		d=dis[d.beforeW][d.beforeH];
	
	for(int i=c.size()-1;i>=0;i--)
	
		cout<<c[i];
	

void DFS(int nowW,int nowH)//入口0,0.出口 49,29

	//左
	if(tryMoveToNewState(nowW,nowH,nowW-1,nowH,'L'))
	
		DFS(nowW-1,nowH);
	
	//右
	if(tryMoveToNewState(nowW,nowH,nowW+1,nowH,'R'))
	
		DFS(nowW+1,nowH);
	
	//上
	if(tryMoveToNewState(nowW,nowH,nowW,nowH-1,'U'))
	
		DFS(nowW,nowH-1);
	
	//下
	if(tryMoveToNewState(nowW,nowH,nowW,nowH+1,'D'))
	
		DFS(nowW,nowH+1);
	
 
int main()

	mapIn();
	dis[0][0].dis=0;
	DFS(0,0);
	PrintOut();
  	return 0;

题目讲解:蓝桥杯·寒假百校真题大联赛(大学B组)(第2期)题目讲解《迷宫》(DFS版本)_哔哩哔哩_bilibili

以上是关于扫雷真题dfs(2022蓝桥杯)的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯算法竞赛系列第八章——提高篇之广度优先搜索(BFS)

第十三届蓝桥杯省赛C++B组 真题题解(详细讲解+代码分析)看这篇就够了~~~

第十三届蓝桥杯省赛C++B组 真题题解(详细讲解+代码分析)看这篇就够了~~~

蓝桥杯Web2022年第十三届蓝桥杯Web大学组国赛真题解析

蓝桥杯·寒假百校真题大联赛(大学B组)(第2期)《迷宫》(DFS版本)

蓝桥杯·寒假百校真题大联赛(大学B组)(第2期)《迷宫》(DFS版本)