迷宫问题:BFS求解最短路径

迷宫描述

5*5的迷宫数组:0可以走;1不可以走;左上角是起点;右下角是终点。

  • 输入样例
0 1 0 0 0
0 1 0 1 0
0 1 0 1 0
0 0 0 1 0
0 1 0 1 0
  • 输出样例
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(3, 1)
(3, 2)
(2, 2)
(1, 2)
(0, 2)
(0, 3)
(0, 4)
(1, 4)
(2, 4)
(3, 4)
(4, 4)

思路

  • 沿上下左右四个方向,使用bfs方法遍历得到路径

    1. 不断从队列中取点,直到队列为空。
    2. 将当前点上下左右四个方向的点加入队列:
      若遇到不合法的位置(超出迷宫之外、该位置是1、该位置已被访问),则不加入队列;
      若即将加入队列的位置是终点,直接返回。
    3. 对每一个添加到队列中的点,记录它之前的一个点(即该位置通过哪一个位置移动得到)
  • 通过记录的路径矩阵,从终点开始递归回溯到起点,输出路径

总结

bfs遍历方法的实质是暴力枚举,从一个点开始层层向外,做到不遗漏。

代码

#include<cstdio>
#include<queue>
using namespace std;

const int N=5;
int Map[N][N];
pair<int,int> Path[N][N]={make_pair(0,0)};
bool visit[N][N]={false};
int directionX[]={0,0,1,-1};
int directionY[]={1,-1,0,0};


void bfs(int row, int column){
	queue<pair<int,int> > q;
	q.push(make_pair(row,column));
	visit[row][column]=true;

	while(!q.empty()){
		pair<int,int> currentPoint=q.front();
		q.pop();

		for(int i=0;i<4;++i){
			int addX=currentPoint.first+directionX[i];
			int addY=currentPoint.second+directionY[i];
			
			if(addX<5&&addX>=0&&addY<5&&addY>=0 && Map[addX][addY]!=1 && !visit[addX][addY]){
				visit[addX][addY]=true;
				Path[addX][addY]=make_pair(currentPoint.first,currentPoint.second);
				if(addX==4&&addY==4)
					return;
				q.push(make_pair(addX,addY));
			}
		}
	}
	return;
}

void pathOutput(int row,int column){
	if(row==0&&column==0){
		printf("(%d, %d)\n",row,column);
		return;
	}
	pathOutput(Path[row][column].first,Path[row][column].second);
	printf("(%d, %d)\n",row,column);
}



int main(void){
	for(int i=0;i<N;++i)
		for(int j=0;j<N;++j)
			scanf("%d",&Map[i][j]);

	bfs(0,0);
	pathOutput(4,4);

	return 0;
}

another one

迷宫描述

S为起点;G为终点;#为墙壁;.为可行走的路。在迷宫地图中寻找从起点到终点的最短路径及其长度。

样例

输入

10 10
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#

输出

22
PATH:
(1 1)
(1 2)
(1 3)
(1 4)
(1 5)
(2 5)
(3 5)
(4 5)
(5 5)
(5 6)
(5 7)
(5 8)
(6 8)
(7 8)
(7 7)
(7 6)
(7 5)
(8 5)
(9 5)
(9 6)
(9 7)
(9 8)

代码

#include<cstdio>
#include<queue>
#include<stack>
using namespace std;

const int MAXN=100;
char maze[MAXN][MAXN];
bool reach[MAXN][MAXN]= {false};
int N,M;
pair<int,int> father[MAXN][MAXN]= {make_pair(0,0)};
int e_x,e_y;

struct xy {
	int x;
	int y;
	int step;

	xy(int i,int j,int s) {
		x=i;
		y=j;
		step=s;
	}
};


int bfs(int row,int coloumn,int s) {
	queue<xy> q;
	xy temp1(row,coloumn,s);
	q.push(temp1);
	reach[row][coloumn]=true; // label
	father[0][1]=make_pair(0,1);

	while(!q.empty()) {
		xy temp2=q.front();
		q.pop();
		int x_direction[]= {0,0,1,-1};
		int y_direction[]= {1,-1,0,0};
		for(int i=0; i<4; ++i) {
			int nx=temp2.x+x_direction[i];
			int ny=temp2.y+y_direction[i];

			if(nx>=0&&nx<N&&ny>=0&&ny<M&&(maze[nx][ny]=='.'||maze[nx][ny]=='G')&& reach[nx][ny]==false) {
				father[nx][ny]=make_pair(temp2.x,temp2.y);
				if(maze[nx][ny]=='G') {
					e_x=nx;
					e_y=ny;
					return temp2.step+1;
				}
				xy temp3(nx,ny,temp2.step+1);
				q.push(temp3);
				reach[nx][ny]=true;
			}
		}
	}
	return 0;
}

int main(void) {
	//freopen("2.txt","r",stdin);
	scanf("%d%d",&N,&M);
	for(int i=0; i<N; ++i)
		scanf("%s",maze[i]);
	
	printf("%d\nPATH: \n",bfs(0,1,0)); //起点在0,1

	stack<pair<int,int> > s;
	pair<int,int> tt(e_x,e_y);
	while(!(tt.first==0&&tt.second==1)) {
		s.push(tt);
		tt=father[tt.first][tt.second];
	}
	while(!s.empty()) {
		pair<int,int> temp=s.top();
		s.pop();
		printf("(%d %d)\n",temp.first,temp.second);
	}

	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值