迷宫之深搜回溯算法
题目描述
核心思路
用char Map0 [ 9 ] [ 9 ] [9][9] [9][9]来存储题目给定的地图,由于是它的数组下标是从0开始的,但是我们想把点的坐标从1开始,所以我们可以对原地图做出转换,得到新地图char Map [ 9 ] [ 9 ] [9][9] [9][9]。
其实这个转换意义不大,只不过说从1开始比较符合常理而已。
由于需要记录路径,所以我们需要两个数组来记录路径, P a t h X [ ] PathX[] PathX[]数组用来记录横坐标, P a t h Y [ ] PathY[] PathY[]用来记录纵坐标。
我们还需要一个判重数组来判断某个点是否已经被访问过了,给这个点打上封条,用bool数组 V i s i t e d [ ] Visited[] Visited[]来记录某个点是否已经被走过。
由于需要记录路径,我们还需要一个变量step,用来记录当前遍历的这个点是在递归树中的第几层。
问题:能不能把xx>=1&&xx<=m&&yy>=1&&yy<=n删去呢?
可以!因为我们已经对原地图做出转换得到了新地图Map,那么Map0中有的全都被映射到新地图Map中了。但是由于新地图Map它是全局数组,初始化为0,当原地图被映射到新地图后,只占用了新地图的第1行到第m行,第1列到第n列,然而并没有用到第0行和第m+1行,第0列到第n+1列。也就是说,相当于给地图加了一圈“空墙”,这些空墙全都是空格,而不是.或者#
所以可以去掉这个判断,因为即使它走出了边界,但是由于此时 M a p [ x x ] [ y y ] Map[xx][yy] Map[xx][yy]的值是空格,不是.或者#,因此不满足 M a p [ x x ] [ y y ] = = ′ . ′ Map[xx][yy]=='.' Map[xx][yy]==′.′这个语句,也进不去语句内部。
问题:能否把step+1改为++step呢?
不能!!!因为假设根节点是第一层,从根节点开始DFS,那么根节点的step=1,假设我们用了++step这个语句,那么由于这个语句的特性,此时step变为了2,但是此时还没有再次递归调用进入DFS函数,那么意义就变为了step=2,也就是根节点是处在第二层了,然后递归进入DFS函数,访问根节点的孩子节点,那么由于递归进入DFS函数了,此时step为2,也就是说孩子节点是处在第二层。但是根节点竟然和孩子节点都处于同一层!!!这是不允许的,所以不能写成++step。
我们应该写成step+1,因为此时step=1,表明根节点是处于第一层,但是它这个step+1语句的结果是会当再次递归进入DFS函数时,它才变为2,也就是说step=2会属于他的孩子节点,而不会属于根节点。
能否不用判重数组Visited呢?
可以!因为我们在新地图中,用.表示可以走,用#表示不可以走,那么当走过了 ( x , y ) (x,y) (x,y)这个点后,我们就可以把这个点设置为#,表示不可以走,即 M a p [ x ] [ y ] = Map[x][y]= Map[x][y]=#。然后再回溯时,再把这个点设置为可走,即 M a p [ x ] [ y ] = ′ . ′ Map[x][y]='.' Map[x][y]=′.′。
画出递归树和路径如下:
能否只做 V i s i t e d [ x ] [ y ] = t r u e Visited[x][y]=true Visited[x][y]=true而不恢复现场 V i s i t e d [ x x ] [ y y ] = f a l s e Visited[xx][yy]=false Visited[xx][yy]=false呢?
不能!!!!分析如下:
代码
#include<iostream>
using namespace std;
char Map0[9][9]={{".#..."},
{".#.#."},
{"....."},
{".#.#."}
};
char Map[9][9];
int m=4,n=4; //m是行数 n是列数
int SouX=3,SouY=1;
int DesX=m,DesY=n;
int PathX[9*9];
int PathY[9*9];
bool Visited[9][9];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void ChangeMap()
{
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
Map[i][j]=Map0[i-1][j-1];
}
void Print(int step)
{
printf("Path:");
for(int i=1;i<=step;i++)
printf("%d,%d ",PathX[i],PathY[i]);
cout <<endl;
}
void DFS(int x,int y,int step)
{
printf("%d,%d step=%d\n",x,y,step);
PathX[step]=x;
PathY[step]=y;
Visited[x][y]=true;
if(x==DesX&&y==DesY)
print(step);
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(Map[xx][yy]=='.'&&!Visited[xx][yy])
{
DFS(xx,yy,step+1);
Visited[xx][yy]=false;
}
}
}
int main()
{
ChangeMap();
DFS(SouX,SouY,step);
return 0;
}