zoukankan      html  css  js  c++  java
  • POJ3984 迷宫问题

    问题链接POJ3984 迷宫问题

    问题简述:参见上述链接。

    问题分析迷宫问题是一个经典的搜索问题,如果是求出一个解,问题就简单很多,通常用DFS来实现。然而,本问题是求路径最短的解,即步数最少的解,就需要用BFS了。

    程序说明使用C语言编写程序的话,处理起来略微复杂一些,需要另外写一个程序。

    这里使用C++语言编程,并且使用STL的队列queue,程序简洁。

    几个要点说明如下:

    1.宏定义 使用宏定义可以增强程序的通用性。类似的问题可以通过修改宏定义来实现,而不需要修改程序。

    2.方向数组 使用方向数组后,各个方向的试探的程序就会变得简洁了。

    3.父节点矩阵 在节点搜索过程中,使用父节点矩阵(二维数组)father[][]。其目的是保证搜索到结果时,能够方便地输出结果,否则很难处理。father[][]中,每个元素都指向其父节点。

    4.避免重复搜索 将搜索过的节点设置为“墙”,可以避免重复搜索,也能够简化程序逻辑。

    5.设置边界 通过设置边界,可以免去矩阵(二维数组)的边界判断,简化了程序逻辑。由于增加边界使得数组下标做了映射,在输出结果时需要做相应的调整。

    AC的C++语言程序如下:

    /* POJ3984 迷宫问题 */
    
    #include <cstdio>
    #include <queue>
    
    using namespace std;
    
    #define MAXN 5
    
    #define STARTROW 1
    #define STARTCOL 1
    #define ENDROW MAXN
    #define ENDCOL MAXN
    
    #define DIRECTSIZE 4
    
    struct direct {
        int drow;
        int dcol;
    } direct[DIRECTSIZE] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
    
    int maze[MAXN+2][MAXN+2];
    
    struct node {
        int row;
        int col;
    };
    
    node father[MAXN+2][MAXN+2];
    
    queue<node> q;
    
    void print_result()
    {
        node path[MAXN*MAXN];
        int count = 0;
    
        // 逆序搜索,放入路径数组中
        path[count].row = ENDROW;
        path[count].col = ENDCOL;
        for(;;) {
            if(path[count].row == STARTROW && path[count].col == STARTCOL)
                break;
    
            path[count+1] = father[path[count].row][path[count].col];
            count++;
        }
    
        // 顺序输出结果
        while(count >= 0) {
            printf("(%d, %d)
    ", path[count].row-1, path[count].col-1);
    
            count--;
        }
    }
    
    void bfs()
    {
        node start; // 设置起始节点
        start.row = STARTROW;
        start.col = STARTCOL;
        q.push(start);
    
        while(!q.empty()) {
            node front = q.front(); q.pop();
            if (front.row == ENDROW && front.col == ENDCOL) {
                print_result();
                return;
            }
            for(int i=0; i<DIRECTSIZE; i++) {
                int nextrow = front.row + direct[i].drow;
                int nextcol = front.col + direct[i].dcol;
                if(maze[nextrow][nextcol] == 0) {
                    father[nextrow][nextcol] = front;
                    node v;
                    v.row = nextrow;
                    v.col = nextcol;
                    q.push(v);
                }
            }
    
            maze[front.row][front.col] = 1; // 搜索过的节点不再搜索
        }
    }
    
    int main(void)
    {
        int i, j;
        for(i=0; i<MAXN+2; i++) {
            maze[0][i] = 1;
            maze[MAXN+1][i] = 1;
            maze[i][0] = 1;
            maze[i][MAXN+1] = 1;
        }
    
        // 输入数据
        for(i=1; i<=MAXN; i++)
            for(j=1; j<=MAXN; j++)
                scanf("%d", &maze[i][j]);
    
        // 广度优先搜索
        bfs(); // 开始搜索
    
        return 0;
    }





    
    
     

  • 相关阅读:
    修复 XE8 for Android 方向传感器 headingX,Y,Z 不会动的问题
    修复 XE8 for Android 分享图片到 Gmail 权限不足的问题
    Firemonkey 载入 Style 皮肤 (*.fsf 二进制文件) 速度测试
    调整 FMX Android 文字显示「锯齿」效果
    [原创工具] ListView 调色盘 (Free)
    有关Linux的可执行程序
    Android 下配置一个 /dev/fb0 节点出来
    Android下运行Linux可执行程序
    数据库的范式
    rk3128 适配 USB 摄像头
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564640.html
Copyright © 2011-2022 走看看