欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

POJ3984 迷宫问题

程序员文章站 2022-05-21 11:25:07
...

问题链接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)\n", 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;
}