走迷宫问题

问题概述

如下由'#'和'.'符号组成的图案表示一个迷宫,在这个迷宫中,'.'表示可以走的路径,可以通过,而'#'表示迷宫的墙,是不能穿过的。我们的目的就是要从迷宫的起点走到终点,找出一条合适的路径,当然最短路径最好。

解决方法

算法思想

站在迷宫中的一个位置上,环顾四周,总共有四个方向可以选择,而这每一个方向都有可能成功,同样也有可能失败。在成功的时候我们就需要顺着这条路径往下走,而失败则需要返回上一个可以选择的位置。因此我们需要保存之前走过路径的状态,很容易能够想到递归的解法,使用系统的栈就可以很好的还原状态。

故我们使用递归的解法,在每一个位置上都进行上、下、左、右四个方向的探索,如果这个方向的路径是有效的,则往下递归。无效则跳过,如果四个方向都没有合适的路径,我们就返回上一层(即上一个位置)重新查找。不断尝试,直到从达到终点为止。

C++实现

#include <iostream>
#include <iomanip>
using namespace std;

// 输出迷宫数组
void printMaze(char maze[][12]) {   
    for (int i = 0; i < 12; ++i) {
        for (int j = 0; j < 12; ++j)
            cout << setw(2) << maze[i][j];
        cout << endl;
    }
    cout << "\n";
}

// 检测当前位置是否有效
bool vaild(char maze[][12], int row, int col) {
    return (row >= 0 && row < 12 && col >= 0 && col < 12
        && maze[row][col] == '.');  // 设置检测'.',避免走回头路
}

// 进行递归查找
void findWay(char maze[][12], int row, int col) {
    // 静态初始化位移数组和终点位置,避免每次递归都重新初始化的开支
    static const int horizontal[4] = { 1, 0, -1, 0 };
    static const int vertical[4] = { 0, 1, 0, -1 };
    static const int finalCol = 11, finalRow = 4;

    maze[row][col] = 'X';   // 标记当前位置
    if (row == finalRow && col == finalCol) {
        cout << "\nSuccessful!\n\n";  // 成功找到出口
        printMaze(maze);
    }
    else {
        int testCol, testRow;
        for (int i = 0; i < 4; ++i) {   // 扫描四个方向
            testCol = col + horizontal[i];
            testRow = row + vertical[i];
            if (vaild(maze, testRow, testCol))  // 如果有效则进行递归查找
                findWay(maze, testRow, testCol);
        }
    }
    maze[row][col] = '.';       // 还原数组状态
}


int main() {
    char maze[12][12] =
    { {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
    {'#', '.', '.', '.', '#', '.', '.', '.', '.', '.', '.', '#'},
    {'.', '.', '#', '.', '#', '.', '#', '#', '#', '#', '.', '#'},
    {'#', '#', '#', '.', '#', '.', '.', '.', '.', '#', '.', '#'},
    {'#', '.', '.', '.', '.', '#', '#', '#', '.', '#', '.', '.'},
    {'#', '#', '#', '#', '.', '#', '.', '#', '.', '#', '.', '#'},
    {'#', '.', '.', '#', '.', '#', '.', '#', '.', '#', '.', '#'},
    {'#', '#', '.', '#', '.', '#', '.', '#', '.', '#', '.', '#'},
    {'#', '.', '.', '.', '.', '.', '.', '.', '.', '#', '.', '#'},
    {'#', '#', '#', '#', '#', '#', '.', '#', '#', '#', '.', '#'},
    {'#', '.', '.', '.', '.', '.', '.', '#', '.', '.', '.', '#'},
    {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'} };     // 迷宫数组
    printMaze(maze);        // 展示迷宫
   
    findWay(maze, 2, 0);

    return 0;
}
posted @ 2020-04-16 01:51  southernEast  阅读(189)  评论(0编辑  收藏  举报