bfs_迷宫问题 POJ - 3984

题目:

定义一个二维数组: 

int maze[5][5] = {

	0, 1, 0, 0, 0,

	0, 1, 0, 1, 0,

	0, 0, 0, 0, 0,

	0, 1, 1, 1, 0,

	0, 0, 0, 1, 0,

};


它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

题目大意:

有一个迷宫,要求探索能否到达终点,如果可以的话输出路径

算法:

bfs 队列

代码:

#include<bits\stdc++.h>
#include<cstdio>
#include<iostream>
using namespace std;
struct node
{
	int x;
	int y;
	int f;
};
struct node que[2501]; //一共最多有2500个元素 
int a[51][51],b[51][51]; //a是存储迷宫的数组 b是标记数组 

void print(int s)  //递归输出
{
    if(que[s].f!=-1)
    {
        print(que[s].f);//根据查找前一个的位置来递归
        cout<<"("<<que[s].x<<", "<<que[s].y<<")"<<endl;
    }
}

int main()
{
	int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; //方向数组 用来遍历四个方向 
	int head,tail; 
	int i,j,k,p,q,tx,ty,flag;
	for(i=0;i<5;i++)
		for(j=0;j<5;j++) 
			cin>>a[i][j]; //输入迷宫信息 
	head=tail=1;  
	que[tail].x=0;
	que[tail].y=0;  //迷宫起点入队 
	que[tail].f=-1; //起点的father标记为-1 便于递归输出路径时使用 
	tail++;         
	b[0][0]=1;      //标记这个点已经走过 
	flag=0;         //flag在判断终止时使用 
	while(head<tail)
	{
		for(k=0;k<4;k++)      
		{
			tx=que[head].x+next[k][0];
			ty=que[head].y+next[k][1];          //四个方向 
			if(tx<0||tx>4||ty<0||ty>4) continue; //越界 
			if(a[tx][ty]==0&&b[tx][ty]==0)  //这个点之前没有走过 并且 是路 
			{
				b[tx][ty]=1;         //标记 
				que[tail].x=tx;    
				que[tail].y=ty;
				que[tail].f=head;    //入队 
				tail++;
			}
			if(tx==4&&ty==4)
			{
				flag=1;
				break;       //到达终点 
			}
		}
		if(flag==1) break;
		head++;         //这个点已经探索完了 出队 
	}
	cout<<"(0, 0)"<<endl;
	if(flag==1)
		 print(head);
	cout<<"(4, 4)";
	return 0;
}

解析:

这道题,要求输出路径,于是决定使用bfs算法,采用队列,可以存储路径。

que[].f 用来存储这个元素的父节点,也就是说-存储这个节点是从哪一个节点探索而来的。

当探索到终点后,使用自定义的递归print函数输出路径。

如果这个点的父亲不是-1(也就是代码最开始,起点入队时,标记的que[tail].f=-1)那么就递归他的父亲节点,知道这个元素的父亲节点是起点,那么就输出他本身,这也就是为什么要单独输出起点。 

至于为什么单独输出终点坐标是因为: 在判断flag==1后就直接break了,没有进行head++。

说完了路径再来说 bfs 总的来说我对bfs的使用没有dfs的顺手

每探索完四个方向,这个时候就要出队,这个地方的出队并不是c++队列的真正出队,他还是存储在了原本的数组中,只是我们认为他已经出队了。

猜你喜欢

转载自blog.csdn.net/baidu_41907100/article/details/84437785