【蓝桥杯】2015决赛 穿越雷区 (DFS || BFS)

题目描述

X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?
已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。

在这里插入图片描述

坦克车只能水平或垂直方向上移动到相邻的区。

输入

输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
输入保证A,B都只出现一次。

输出

要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1

样例输入

5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -

样例输出

10

BFS代码:

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=110;
bool vis[maxn][maxn]={
    
    false}; //记录是否走过
char site[maxn][maxn]; //地图
int n,ans=1<<27,sx,sy,cnt=0;
int dx[4]={
    
    0,0,-1,1}; //四个方向
int dy[4]={
    
    1,-1,0,0};

struct node{
    
     
	int x,y,step;
	node(int a,int b,int c){
    
    x=a;y=b;step=c;}
};

void bfs()
{
    
    
	queue<node> q;
	q.push(node(sx,sy,0));
	vis[sx][sy]=1;
	
	while(!q.empty())
	{
    
    
		node now = q.front();
		q.pop();
		
		int x=now.x;
		int y=now.y;
		int step=now.step;
		
		if(site[x][y]=='B')  //到达终点
		{
    
    
			cout<<step;
			break;
		}
		
		for(int i=0;i<4;i++)
		{
    
    
			int newx=x+dx[i];
			int newy=y+dy[i];
			if(!vis[newx][newy] && newx>=0 && newx<n && newy>=0 && newy<n && site[newx][newy]!=site[x][y])
			//没访问过 && 在边界内 && 和上一步的字符不同
			{
    
    
				vis[newx][newy]=1;
				q.push(node(newx,newy,step+1));
			}
		}
	}
	
}

int main() 
{
    
    
	cin>>n;
	for(int i=0;i<n;i++)
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			cin>>site[i][j];
			if(site[i][j]=='A') sx=i,sy=j; //确定起点
		}
	}
	
	bfs();
	return 0;
}


DFS代码:

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=110;
char site[maxn][maxn]; //地图
bool vis[maxn][maxn]={
    
    false}; //记录是否走过
int n,ans=1<<27,sx,sy;
int dx[4]={
    
    0,0,-1,1}; //四个方向
int dy[4]={
    
    1,-1,0,0};

void dfs(int x,int y,int step)  
{
    
    
	if(step>=ans) return; //剪枝,当前步数已经无法再优化了
	
	if(site[x][y]=='B') //到终点,更新ans
	{
    
    
		ans=min(ans,step);
		return;
	}
	
	for(int i=0;i<4;i++)
	{
    
    
		int newx=x+dx[i];
		int newy=y+dy[i];
		if(!vis[newx][newy] && newx>=0 && newx<n && newy>=0 && newy<n && site[newx][newy]!=site[x][y])
		//没访问过 && 在边界内 && 和上一步的字符不一样
		{
    
    
			vis[newx][newy]=1;
			dfs(newx,newy,step+1);
			vis[newx][newy]=0;
		}
	}
}

int main() 
{
    
    
	cin>>n;
	for(int i=0;i<n;i++)
	{
    
    
		for(int j=0;j<n;j++)
		{
    
    
			cin>>site[i][j];
			if(site[i][j]=='A') sx=i,sy=j; //找到起点
		}
	}
	
	dfs(sx,sy,0);
	if(ans!=1<<27) cout<<ans;
	else cout<<-1;
	return 0;
}

这耗时差距很明显 (第一行是BFS,第二行DFS)

因为BFS的特性,第一次到终点时必定是最短的,而DFS需要把所有路径都找一遍,然后进行更新,寻找ans

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45260385/article/details/109457798