递归解谜:最短路径找仙药

需积分: 19 9 下载量 120 浏览量 更新于2024-08-19 收藏 1.73MB PPT 举报
"这篇资源主要讨论的是一个基于C++编程的最短路径问题,即‘仙岛求药’,这是一个典型的迷宫问题。题目描述了一个少年李逍遥在寻找仙药的过程中,需要通过一个充满怪物的迷宫,目标是找出从起点到仙药所在地的最短路径,避开怪物并经过最少的方格。输入数据包含迷宫的尺寸以及各个方格的状态,输出要求是找到最短路径的步数或在找不到路径时输出-1。" 在解决这类问题时,通常会使用深度优先搜索(DFS)或广度优先搜索(BFS)算法。对于迷宫问题,BFS通常用于找最短路径,因为它保证找到的第一个解是最优解。在这个案例中,由于题目要求找出最短路径,我们可能会选择使用BFS。 首先,我们需要定义一个二维数组来表示迷宫,数组的每个元素代表一个方格的状态,如‘@’表示起点,‘.’表示安全通道,‘#’表示怪物,‘*’表示仙药。在C++中,我们可以创建一个`char a[M][N]`数组来存储这些信息。 接下来,我们利用BFS算法进行搜索。BFS的基本思想是从起点开始,将起点放入队列,然后逐个检查队列中的节点,将其相邻且未访问过的节点加入队列,并更新这些节点的距离。当找到仙药位置时,记录下到达仙药的步数。如果队列为空且仍未找到仙药,说明不存在路径,输出-1。 在实现过程中,还需要一个二维数组`visited[M][N]`来记录每个方格是否已被访问,避免重复探索。同时,需要维护一个变量`steps`来记录已经走过的步数。 代码实现可能如下: ```cpp #include <queue> using namespace std; int bfs(int m, int n, char a[M][N], int steps, int x, int y) { queue<pair<int, int>> q; // 使用队列存储待处理节点 q.push({x, y}); // 将起点加入队列 visited[x][y] = 1; // 标记起点已访问 while (!q.empty()) { int currX = q.front().first; int currY = q.front().second; q.pop(); // 如果找到仙药,返回步数 if (a[currX][currY] == '*') return steps + 1; // 检查上下左右四个方向 for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { int newX = currX + dx, newY = currY + dy; // 跳过当前位置和越界的位置 if (newX < 0 || newX >= m || newY < 0 || newY >= n || visited[newX][newY] || a[newX][newY] == '#') continue; q.push({newX, newY}); visited[newX][newY] = 1; steps++; } } } // 无法找到仙药,返回-1 return -1; } int main() { // 输入迷宫信息 // 调用bfs函数 // 输出结果 } ``` 以上代码中,`bfs`函数实现了BFS搜索,`main`函数负责读取输入并调用`bfs`函数。注意,实际的代码需要添加错误处理和输入输出的具体实现。 此外,递归也是一个重要的概念,虽然在这个问题中,我们主要使用了BFS而非递归。但是,递归在解决类似迷宫问题时也有其应用场景,例如在一个方格内尝试所有可能的方向,如果当前方向不可行则回溯到上一步,这种策略可以转化为递归函数实现。不过,由于BFS更适用于寻找最短路径,所以在这个问题中,我们倾向于使用BFS。