Files
python/C++专题课程/回溯算法/迷宫/C++ 用回溯法求解迷宫问题(递归).cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

104 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
/*
一、定义:
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。
但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就
退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
用回溯法求解问题时常使用递归方法进行试探,或使用栈帮助向前试探和回溯。
二、思路:
1.用一个二维数组表示迷宫:
数组中的值如果是1,则表示该位置是墙壁,不能通行;
如果等于0,表示该位置是通路;
用一个标记数组,标记该位置是否被访问过;
2.迷宫前进的方向:要定义一个结构体存储方向
可能有8个方向:东,东南,南,西南,西,西北,北,东北
3.给一个入口和出口的坐标,从入口入手:
循环入口的8个方向,如果位置通,则递归该位置,一直递归下去,直到到达出口或者所有方向的路不通回溯;
*/
// 默认迷宫的行数和列数
const int XLEN = 14, YLEN = 17;
int m, p; // 出口坐标
int maze[XLEN + 2][YLEN + 2]; // 迷宫数组
int mark[XLEN + 2][YLEN + 2]; // 访问标记数组
// 结果体,代表一个二维数组的元素,a和b是x,y方向的偏移
struct Offsets {
int a, b;
};
// 因为不需要输出方向,所以把方向去掉
Offsets direction[8] =
{{-1, 0},
{-1, 1},
{0, 1},
{1, 1},
{1, 0},
{1, -1},
{0, -1},
{-1, -1}
};
// 解决迷宫问题的递归算法
bool seekPath(int x, int y) {
// 从迷宫某一位置[i][j]开始,寻找出口[m][p]的一条路径,如果找到,则函数返回true
int i, g, h; // g, h记录位置信息
if (x == m && y == p) // m和p是出口坐标
return true;
// 循环遍历(x, y)的8个方向
for (i = 0; i < 8; i++) {
g = x + direction[i].a;
h = y + direction[i].b;
// 找下一位置寻找通向出口的路径
if (maze[g][h] == 0 && mark[g][h] == 0) { // 如果通且未被访问过
mark[g][h] = 1; // 标记为已访问过
if (seekPath(g, h)) { // 递归试探
cout << "(" << g << ", " << h << "),"; // 逆向输出路径坐标
return true;
}
}
// 回溯,换一个方向再试探通向出口的路径
}
return false; // 找不到通向出口的路径
}
int main(int argc, const char *argv[]) {
//读取数据文件
freopen("./data.txt", "r", stdin);
int i, j, x, y;
// 输入迷宫数据
for (i = 0; i < XLEN; i++) {
for (j = 0; j < YLEN; j++) {
cin >> maze[i][j];
//初始化标记数组
mark[i][j] = 0;
}
}
//输入入口位置坐标
cin >> x >> y;
//输入出口位置坐标
cin >> m >> p;
// 从入口开始
mark[x][y] = 1;
// 调用求解迷宫的递归算法
if (seekPath(x, y)) // 成功
{
cout << "(" << x << ", " << y << ")" << endl;
} else {
cout << "找不到从入口到出口的路径!" << endl;
}
return 0;
}