大家好,这里是木子古月的学习日记
今天要学习的是迷宫问题,运用的是深度优先算法
废话不多说,我写一下我自己对这个算法的理解,以及问题解决的步骤
对于一个迷宫问题,首先我们要了解是题目
我下面就简单出一个题目
红色的代表起点和终点,黑色的代表可以走的路,白色为墙壁;
由此我们要去解决的是从起点到终点的最短路径问题:
因此我们开始逐步分析
- 关于道路和墙壁如何识别的问题:可以建立一个二维数组用来存储墙壁和道路信息
比如定义一个数组
int wall [5] [5];
我们在这里用0代表道路,1代表墙壁,提前读入道路信息;
- 关于移动方向:首先我们移动方向一般只有 上、下、左、右 这四个方向,如果有斜向的方向另说,因此我们可以制定一个顺序,去依次访问这些方向的单元格(道路)。
这里我们制定的方向为:左 、 下 、 右 、 上。
可以写一个数组来记录路是否走过,以防止回头的现象出现
Int st [5] [5] ;
走过的话把相应的单元格(道路)改为1;
因此我们可以写一个部分去走四个方向的路:
左方向:
st [x][y] = 1;
if (wall[x+1][y] == 0 && st[x+1][y] == 0) {
st[x+1][y] = 1;
fun(x+1, y, step + 1);
st[x+1][y] = 0;
下方向:
st [x][y] = 1;
if (wall[x+1][y] == 0 && st[x+1][y] == 0) {
st[x+1][y] = 1;
fun(x+1, y, step + 1);
st[x+1][y] = 0;
左方向:
st [x][y] = 1;
if (wall[x-1][y] == 0 && st[x-1][y] == 0) {
st[x-1][y] = 1;
fun(x-1, y, step + 1);
st[x-1][y] = 0;
上方向:
st [x][y] = 1;
if (wall[x][y-1] == 0 && st[x][y-1] == 0) {
st[x][y-1] = 1;
fun(x, y-1, step + 1);
st[x][y-1] = 0;
我们也可以简化一下:
用一个循环的方法来实现这个步骤:
int kx[4] = { 1,0,-1,0 };
int ky[4] = { 0,1,0,-1 };
for (int k = 0; k < 4; k++) {
int tx = x1 + kx[k];
int ty = y1 + ky[k];
st[x1][y1] = 1;
if (wall[tx][ty] == 0 && st[tx][ty] == 0) {
st[tx][ty] = 1;
fun(tx, ty, step + 1);
st[tx][ty] = 0;
}
}
这里不难理解就是把四个方向所要改变的X方向和Y方向的值记录在数组里面
不细说了。
然后我们要做的就是比较步数大小
这十分简单,我们只需要在开头写一个判断和返回就可以:
if (x1 == 29 && y1 == 49) {
if (min < step)
min = step;
return;
}
到这里,我们就已经把步骤写完了:
下面就是实现函数具体代码,主函数可以根据自己的需要添加:
#include <stdio.h>
int min;
int kx[4] = { 1,0,-1,0 };
int ky[4] = { 0,1,0,-1 };
int wall[5][5], st[5][5] = {0};
void fun(int x1, int y1,int step) {
if (x1 == 4 && y1 == 4) {
if (min < step)
min = step;
return;
}
for (int k = 0; k < 4; k++) {
int tx = x1 + kx[k];
int ty = y1 + ky[k];
st[x1][y1] = 1;
if (wall[tx][ty] == 0 && st[tx][ty] == 0) {
st[tx][ty] = 1;
fun(tx, ty, step + 1);
st[tx][ty] = 0;
}
}
return;
}
int main() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
scanf("%d",&wall[i][j]);
}
}
fun(0,0,0);
printf("%d", min);
}