问题链接:。
问题简述:参见上述链接。
问题分析:迷宫问题是一个经典的搜索问题,如果是求出一个解,问题就简单很多,通常用DFS来实现。然而,本问题是求路径最短的解,即步数最少的解,就需要用BFS了。
程序说明:使用C语言编写程序的话,处理起来略微复杂一些,需要另外写一个程序。
这里使用C++语言编程,并且使用STL的队列queue,程序简洁。
几个要点说明如下:
1.宏定义 使用宏定义可以增强程序的通用性。类似的问题可以通过修改宏定义来实现,而不需要修改程序。
2.方向数组 使用方向数组后,各个方向的试探的程序就会变得简洁了。
3.父节点矩阵 在节点搜索过程中,使用父节点矩阵(二维数组)father[][]。其目的是保证搜索到结果时,能够方便地输出结果,否则很难处理。father[][]中,每个元素都指向其父节点。
4.避免重复搜索 将搜索过的节点设置为“墙”,可以避免重复搜索,也能够简化程序逻辑。
5.设置边界 通过设置边界,可以免去矩阵(二维数组)的边界判断,简化了程序逻辑。由于增加边界使得数组下标做了映射,在输出结果时需要做相应的调整。
AC的C++语言程序如下:
/* POJ3984 迷宫问题 */#include#include using namespace std;#define MAXN 5#define STARTROW 1#define STARTCOL 1#define ENDROW MAXN#define ENDCOL MAXN#define DIRECTSIZE 4struct 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 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