POJ——3984迷宫问题(BFS+回溯)

迷宫问题
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 14568   Accepted: 8711

Description

定义一个二维数组: 
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<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
#define MMINF(x) memset(x,INF,sizeof(x))
typedef long long LL;
const double PI=acos(-1.0);
struct info
{
	int x;
	int y;
	int prex;
	int prey;
};
info direct[4]={{0,1},{0,-1},{1,0},{-1,0}};
info operator+(const info &a,const info &b)
{
	info c;
	c.x=a.x+b.x;
	c.y=a.y+b.y;
	return c;
}
int pos[5][5],vis[5][5];
info history[5][5]={{0,0,-1,-1}};
inline bool check(const info &a)
{
	if((!vis[a.x][a.y])&&(!pos[a.x][a.y])&&(a.x>=0&&a.y>=0&&a.x<5&&a.y<5))
		return true;
	return false;
}
int main(void)
{
	int i,j;
	for (i=0; i<5; i++)
	{
		for (j=0; j<5; j++)
		{
			scanf("%d",&pos[i][j]);
		}
	}
	queue<info>Q;
	Q.push(history[0][0]);
	vis[history[0][0].x][history[0][0].y]=1;
	while (!Q.empty())
	{
		info now=Q.front();
		Q.pop();
		for (int i=0; i<4; i++)
		{
			info v=now+direct[i];
			v.prex=now.x;
			v.prey=now.y;
			if(check(v))
			{
				Q.push(v);
				vis[v.x][v.y]=1;
				history[v.x][v.y]=v;
			}
		}
		if(now.x==4&&now.y==4)
			break;
	}
	stack<info>ans;
	info k=history[4][4];
	puts("(0, 0)");
	while (k.prex!=-1)
	{
		ans.push(k);
		k=history[k.prex][k.prey];
	}
	while (!ans.empty())
	{
		info t=ans.top();
		printf("(%d, %d)
",t.x,t.y);
		ans.pop();
	}	
	return 0;
}
原文地址:https://www.cnblogs.com/Blackops/p/5766312.html