H - 迷宫问题 POJ3984 (BFS+DFS)

11 篇文章 0 订阅

搜索的简单题,一开始没太有很好的思路时, 从网上开了一些题解, 感觉他们过于小题大做,写的代码过于麻烦,繁琐。 于是我就想到了一个相对比较简单的算法。


解题思路:

分为两个步骤

1. 首先用最朴素的BFS求出从起点到终点的最小距离 即(0 , 0)——>(4, 4)的迷宫最短距离, 并记录这个最短距离dis;

2.再从起点(0 ,0)利用DFS边走边记录坐标,在正好走的距离为dis时检查所处的位置是否为终点(4,4),如果不是将递归的DFS逐级返回,如此反复直到走到终点(4, 4)。

3.最好再将记录的坐标打印出来即可。

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)
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>

using namespace std;
typedef pair<int , int> P;

int maze[10][10];
int d[10][10];
int mark[10][10];
int mark2[10][10];
typedef struct
{
    int x;
    int y;
}DF;
DF dfss[30];

int bfs(void)
{
    queue<P> que;
    que.push(P(0, 0));
    d[0][0] = 0;
    mark[0][0];
    while(que.size())
    {
        P p = que.front();
        que.pop();
        if(p.first == 4 && p.second == 4)
            break;
        for(int dx = -1; dx <= 1; dx++)
        {
            for(int dy = -1; dy <= 1 ; dy++)
            {
                int nx = p.first + dx;
                int ny = p.second + dy;
                if(abs(dx) != abs(dy) && nx >= 0 && nx < 5 && ny >= 0 && ny < 5 && mark[nx][ny] == 0 && maze[nx][ny] == 0)
                {
                    que.push(P(nx, ny));
                    d[nx][ny] = d[p.first][p.second] + 1;
                    mark[nx][ny] = 1;
                }
            }
        }
    }
    return d[4][4];
}

bool dfs(int x, int y, int dis)
{
    dfss[dis].x = x;
    dfss[dis].y = y;
    mark2[x][y] = 1;
    if(dis == 0)
    {
        return (x == 4 && y == 4);
    }
    if(x -1 >= 0 && mark2[x-1][y] == 0 && maze[x-1][y] == 0)
    {
        mark2[x-1][y] =1;
        if(dfs(x-1, y ,dis-1))
            return true;
    }
    if( x + 1 < 5 && mark2[x+1][y] == 0 && maze[x+1][y] == 0)
    {
        mark2[x+1][y] = 1;
        if(dfs(x +1 , y , dis-1))
            return true;
    }
    if(y -1 >= 0 && mark2[x][y-1] == 0 && maze[x][y-1] == 0)
    {
        mark2[x][y-1] =1;
        if(dfs(x, y-1, dis - 1))
            return true;
    }
    if( y + 1 < 5 && mark2[x][y+1] == 0 && maze[x][y+1] == 0)
    {
        mark2[x][y+1] =1;
        if(dfs(x , y + 1, dis - 1))
            return true;
    }





    return false;
}



int main()
{
    int cnt = 0;
    for(int i = 0 ; i < 5 ; i++)
    {
        for(int j = 0 ; j < 5 ; j++)
        scanf("%d", &maze[i][j]);
    }
    int dis = bfs();
//    for(int i = 0 ; i < bfs() ; i++)
//    {
//        dis[i] = i;
//    }
//    printf("dis:%d\n", dis);
    dfs(0, 0, dis);
    for(int i = dis ; i >= 0 ; i--)
    {
        printf("(%d, %d)\n", dfss[i].x, dfss[i].y);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值