|
用深度优先搜索来实现这个方法,dfs函数的功能是解决当前应该怎么办,所以我们每走到一个点都需要进行处理:
①判断我们有没有走到迷宫的终点,如果没有到达就找出下一步可以走的地方。所以dfs函数只需要维护2个参数,分别是当前这个点的 x 坐标和y 坐标
void DFS(int x, int y)
{
//判断是否找到了迷宫的出口
if (x == 4 && y == 4)
{
flag = 1;
return;//返回上一层dfs函数
}
②如果没有到达迷宫的终点, 则找出下一步可以走的地方,因为有四个方向可以走,为了操作方便,我定义了一个方向数组
int next[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };//向右,向下,向左,向上
通过这个方向数组,使用循环就很容易获得下一步的坐标。 这里将下一步的横坐标用 tx存储, 纵坐标用 ty 存储。如果循环结束,发现无路可走,就会回退一步,即返回上一层dfs函数
for (int k = 0; k < 4; k++)
{
//计算下一个点的坐标
tx = x +next[k][0];
ty = y + next[k][1];
③接下来我们就要对下一个点(tx,ty)进行一些判断。 包括是否越界,是否为障碍物,以及这个点是否已经在路径中 (即避免重复访问一个点,需要用 book[tx][ty]来记录格子(tx,ty)是否已经在路径中
如果这个点符合所有的要求, 就对这个点进行下一步的扩展,即dfs(tx,ty)
for (int k = 0; k < 4; k++)
{
//计算下一个点的坐标
tx = x +next[k][0];
ty = y + next[k][1];
//不能越界
if (tx < 0 || ty < 0 || tx >= 5 || ty >= 5)
continue;
//判断该点是否为障碍物或者已经在路径中
if (maze[tx][ty] == 0 && book[tx][ty] == 0)
{
book[tx][ty] =1;
DFS(tx, ty);//开始尝试这一个点
//可以走到终点,则返回
if (flag)
return;
}
}
//循环结束后,发现尝试失败,则取消这个点的标记,并回退到上一层dfs函数
book[tx][ty] = 0;
step--;
return;
完整代码:
#include<iostream>
using namespace std;
int maze[10][10];
int pos[10][10];
int book[10][10];
int step,flag;
void DFS(int x, int y)
{
//记录到达位置的下标
pos[step][0] = x; pos[step][1] = y;
step++;
//标记这个点已经走过
book[x][y] = 1;
//判断是否找到了迷宫的出口
if (x == 4 && y == 4)
{
flag = 1;
return;//返回上一层dfs函数
}
int next[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };//向右,向下,向左,向上
int tx, ty, k;
//枚举四种走法
for (int k = 0; k < 4; k++)
{
//计算下一个点的坐标
tx = x +next[k][0];
ty = y + next[k][1];
//不能越界
if (tx < 0 || ty < 0 || tx >= 5 || ty >= 5)
continue;
//判断该点是否为障碍物或者已经在路径中
if (maze[tx][ty] == 0 && book[tx][ty] == 0)
{
book[tx][ty] =1;
DFS(tx, ty);//开始尝试这一个点
//可以走到终点,则返回
if (flag)
return;
}
}
//尝试失败,取消这个点的标记
book[tx][ty] = 0;
step--;
return;
}
int main()
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
cin >> maze[i][j];
}
DFS(0, 0);
for (int i = 0; i < step; i++)
cout << "(" << pos[i][0] << ", " << pos[i][1] << ")" << endl;
return 0;
}