第十届蓝桥杯 E走迷宫(BFS)

思路

我相信能查到这儿的伙伴一定已经看过了题目了,那就开门见山,谈谈这题的思路。在考场上,我第一想法是用DFS,尝试了一下,没有跑出来,以为DFS用的隐式的栈,所以无法直接跑出答案。回来后,我用BFS尝试了一下,成功解出了答案。代码和注释如下。

#include<queue>
#include<windows.h>
#include<iostream>
using namespace std;
typedef pair<int,int> p;
const int INF=100000000;
#define row 30
#define cow 50
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
char graph[35][55];
int tar[35][55];
pair<int,int> qian[35][55];
void bfs()
{
	queue<p> s;
	int i,j;
	for(i=0;i<row;i++)				//初始距离设一下这样就没必要记录是否访问过,一举两得
		for (j=0;j<cow;j++)
			tar[i][j]=INF;
	s.push(pair<int,int>(0,0));		//头结点入栈
	tar[0][0]=0;
	while(s.size())
	{
		p q=s.front();
		s.pop();
		if (q.first==row-1 && q.second==cow-1)			//找到目标结束
			return;
		for (i=0;i<4;i++)
		{
			int nx=q.first+dx[i];
			int ny=q.second+dy[i];
			if (0<=nx && nx<row && ny>=0 && ny<cow && graph[nx][ny]!='1' && tar[nx][ny]==INF)	//1.不能越界  2.该点可访问  3.该点未访问过	
			{
				s.push(pair<int ,int>(nx,ny));		//搜到该点,就入栈
				qian[nx][ny]=pair<int,int>(q.first,q.second);	//记录前一个结点,便于回溯
				tar[nx][ny]=tar[q.first][q.second]+1;		//路径加一
			}
		}
	}
	
}
void show(int cur_x,int cur_y,int qi_x,int qi_y)
{
	if (cur_x==qi_x+1 && cur_y==qi_y)			//右
	{
		cout<<"R";
	}
	else if (cur_x==qi_x-1 && cur_y==qi_y)		//左
	{
		cout<<"L";
	}
	else if (cur_x==qi_x && cur_y==qi_y+1)		//下
	{
		cout<<"D";
	}
	else if (cur_x==qi_x && cur_y==qi_y-1)		//上
	{
		cout<<"U";
	}
}
int main ()
{
	int i,j;
	for (i=0;i<row;i++)
		for (j=0;j<cow;j++)
			cin>>graph[i][j];
	bfs();
	int qi_x,qi_y,temp;
	qi_x=row-1;qi_y=cow-1;
	while(qi_x!=0 || qi_y!=0)				//回溯法
	{
		show(qi_x,qi_y,qian[qi_x][qi_y].first,qian[qi_x][qi_y].second);		//倒序找该点
		temp=qi_x;							//此处注意因为q_x将被改变,所以必须先存一个值
		qi_x=qian[qi_x][qi_y].first;
		qi_y=qian[temp][qi_y].second;
	}
	cout<<tar[row-1][cow-1]<<endl;
	return 0;
}

优化

在网上看到诸位大牛在使用BFS或DFS搜索时都会用到剪枝的方法提高算法的效率,等我日后有空再补上优化过程。

初次写博客,多谢各位捧场,如有不足,欢迎联系Q:1394270593
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值