#include <stdio.h>
int n, m, p, q, min=999999; //n和m分别为行和列, p和q分别为终点的x,y坐标, min是最小步数
int a[51][51], book[51][51]; //a数组代表障碍物, book 数组标记已经走过的路
void dfs(int x, int y, int step) ;
int main() {
int i, j, startX, startY;
// 读入n和m, n为行, m为列
scanf("%d %d", &n, &m);
// 读入迷宫
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
scanf("%d", &a[i][j]);
// 读入起点和终点的坐标
scanf("%d %d %d %d", &startX, &startY, &p, &q);
// 从起点开始搜索
book[startX][startY] = 1; //标记起点已经在路径中, 防止后面重复走
// 第一个参数是起点的x坐标, 第二个参数是起点的y坐标, 第三个参数是初始步数为0
dfs(startX, startY, 0);
// 因为最小步数min被定义在了全局变量的位置, 所以dfs函数不需要返回值
// 输出最小步数
printf("%d", min);
getchar(); getchar();
return 0;
}
void dfs(int x, int y, int step) {
// 此处太妙了, 定义了一个二位数组next 来表示下一步行走的动作
int next[4][2] = { {0,1}, //向右走
{1,0}, //向下走
{0, -1}, //向左走
{-1, 0}}; // 向上走
int tx, ty, k;
// 判断是否达到小哈的位置
if(x==p && y==q) {
// 更新最小值
if(step < min) min=step;
return; // 若达到了小哈的位置, 就返回上一次递归调用的地方
}
// 枚举四种走法
for(k=0; k<=3; k++) { // k代表了走的方向, next二位数组的第二个方括号代表了x和y
// 计算下一个点的坐标
tx = x + next[k][0];
ty = y + next[k][1];
// !!! 判断是否越界
if(tx<1 || ty<1 || tx>n || ty>m) {
continue;
}
// 判断该点是否为障碍物 或 已经在路径中 (即判断下一步走的那个点是否合理,
// 合理则进行递归, 不合理便继续循环
if(a[tx][ty]==0 && book[tx][ty]==0) { // a代表障碍物(1代表有,0代表无), book代表是否走过
book[tx][ty] = 1; //标记这个点已经走过
dfs(tx, ty, step+1); //开始尝试下一个点
book[tx][ty] = 0; //尝试结束, 取消这个点的标记
}
}
return;
}
《啊哈算法》 解救小哈(深度优先算法——走迷宫实战) P86
最新推荐文章于 2022-04-24 18:53:41 发布