迷宫问题(BFS+保存路径) POJ No.3984

Description

定义一个二维数组:

int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

 

分析:
因为上一篇中的迷宫问题只需要输出最小步数一个整数,所以可以将用来表示访问过的状态数组和递增步数的数组合为一个整型二维数组。
而这里需要记录的是路径,即每一步走过的坐标,所以可以另设一个自定义的数组用来存坐标,另设一个布尔类型数组表示访问状态。在后
面遍历记录路径的数组时发现仍然需要最小步数来做判断条件,所以自定义了一个含x,y,z的类,z用来计算最小步数。

关于保存路径:

将已经访问过的状态用标记管理起来,就可以实现由近及远的搜索,从终点往回遍历foot一定是最短路径。你可以找一条比最短路径长的路径,然后分析路径上的特殊状态会发现,因为被访问过的状态不能再被访问,所以最长路径上的有些状态已经被短路径访问过,所以这条长路径会在这中断而不会到达终点,所以将已经访问过的状态用标记管理起来,就可以实现由近及远的搜索。

 

代码如下:

 

    #include <iostream>
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<cstring>
    #include<string>
    #include<vector>
    #include<set>
    #define INF 0x3f3f3f3f
    #define MAX 10

    using namespace std;

    struct node{
        int x, y, z;//z:走到该点的步数
    };
    int mp[MAX][MAX];
    node foot[MAX][MAX];//记录路径,现在的点存上一步的点
    int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
    bool visit[MAX][MAX];

    int bfs(){
        queue<node> que;
        que.push((node){
                 0,0,0
                 });
        while(!que.empty()){
            node p = que.front();
            que.pop();
            if(p.x == 4 && p.y == 4) return p.z;
            if(visit[p.x][p.y]) continue;
            for(int i = 0; i < 4; i++){
                node n;
                n.x = p.x + dx[i];
                n.y = p.y + dy[i];
                n.z = p.z + 1;
                if(0 <= n.x && n.x < 5 && 0 <= n.y && n.y < 5){
                    if(!visit[n.x][n.y] && !mp[n.x][n.y]){
                        que.push(n);
                        foot[n.x][n.y].x = p.x;
                        foot[n.x][n.y].y = p.y;
                    }
                }
            }
        }
        return 0;

    }

    int main(){
        memset(visit, false, sizeof(visit));
        for(int i = 0; i < 5; i++)
            for(int j = 0; j < 5; j++){
                scanf("%d", &mp[i][j]);
            }
        int len = bfs();
        int a = 4, b = 4;
        //将路径保存到arr数组,便于正向输出路径
        node arr[MAX];
        for(int i = 0; i < len; i++){
            arr[i].x = foot[a][b].x;
            arr[i].y = foot[a][b].y;
            a = arr[i].x;
            b = arr[i].y;
        }
        for(int i = len - 1; i >= 0; i--){
            printf("(%d, %d)
", arr[i].x, arr[i].y);
        }
        printf("(4, 4)
");
        return 0;
    }

 

 



 
祝你早日攒够失望,然后开始新的生活。
原文地址:https://www.cnblogs.com/LuRenJiang/p/6918553.html