BFS和DFS方法解决走迷宫问题

链接:https://www.nowcoder.com/questionTerminal/6276dbbda7094978b0e9ebb183ba37b9
来源:牛客网
题目:

NowCoder最喜欢游乐场的迷宫游戏,他和小伙伴们比赛谁先走出迷宫。
现在把迷宫的地图给你,你能帮他算出最快走出迷宫需要多少步吗?

输入描述:
输入包含多组数据。

每组数据包含一个10*10,由“#”和“.”组成的迷宫。其中“#”代表墙;“.”代表通路。

入口在第一行第二列;出口在最后一行第九列。

从任意一个“.”点都能一步走到上下左右四个方向的“.”点。


输出描述:
对应每组数据,输出从入口到出口最短需要几步。
示例1

输入

#.########
#........#
#........#
#........#
#........#
#........#
#........#
#........#
#........#
########.#
#.########
#........#
########.#
#........#
#.########
#........#
########.#
#........#
#.######.#
########.#

输出

16
30
//自己的一些看法,望各位批评指正
// BFS解法,利用了一个队列queue装载pair<int x,int y>类型数据(对应格子坐标)
//之所以使用queue,是因为队列的先进先出特性正好对应了
//广度优先搜索(BFS)的迭代
//个人认为这道题用BFS效率高些,与DFS相比因为没有使用递归反复更新格子里的值,
//时间复杂度较低,但题目迷宫较小所以运行时间没有太大差别。
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
int a[10][10] = {0};//记录格子状态,0代表没有走过
char str[10][10];//记录迷宫
int bfs(int x0,int y0)
{
    queue<pair<int,int> > q;//存储格子坐标的队列
    pair<int,int> p;
    int x,y;
    q.push(make_pair(x0,y0));
    while(1)
    {
        p = q.front();
        x = p.first;
        y = p.second;
        if(x==9&&y==8)//走到终点就退出循环
            return a[9][8];
/*
下面是4个if语句,分别对应格子的上、下、左、右四个相邻的格子
如果这个格子符合条件(坐标不越界,同时不是'#',并且之前没有走过)
就把它放入队列。这里需要注意的是,队列先进先出就保证了离出口近的
格子总是比离出口远的格子先处理,也就是说只有当广度(离出口距离比如2)
的所有格子都pop()出队列,广度为3的格子才变为队首元素。就这样一点点
增加广度,直到走到出口。
当然你也可以用一个for循环替代这里的4个if,但我想写的详细点*/
        if((x-1)>=0&&(x-1)<=9&&y>=0&&y<=9&&a[x-1][y]==0&&str[x-1][y]!='#')
        {
            a[x-1][y]=a[x][y]+1;
            q.push(make_pair(x-1,y));
        }
        if((x+1)>=0&&(x+1)<=9&&y>=0&&y<=9&&a[x+1][y]==0&&str[x+1][y]!='#')
        {
            a[x+1][y]=a[x][y]+1;
            q.push(make_pair(x+1,y));
        }
        if(x>=0&&x<=9&&(y-1)>=0&&(y-1)<=9&&a[x][y-1]==0&&str[x][y-1]!='#')
        {
            a[x][y-1]=a[x][y]+1;
            q.push(make_pair(x,y-1));
        }
        if(x>=0&&x<=9&&(y+1)>=0&&(y+1)<=9&&a[x][y+1]==0&&str[x][y+1]!='#')
        {
            a[x][y+1]=a[x][y]+1;
            q.push(make_pair(x,y+1));
        }
        q.pop();//判断完上下左右4个格子后该格子应该出队
    }
}
int main()
{
    char c;
    while(~scanf("%c",&c))
    {
        str[0][0] = c;
        for(int i=1;i<10;i++)
        {
            scanf("%c",&c);
            str[0][i] = c;
        }
        getchar();//吃掉末尾的换行符
        for(int i=1;i<10;i++)
        {
            for(int j=0;j<10;j++)
            {
                scanf("%c",&c);
                str[i][j] = c;
            }
            getchar();//吃掉末尾的换行符
        }
        printf("%d\n",bfs(0,1));
        memset(a,0,sizeof(a));//初始化全局变量a数组
    }
    return 0;
}
//下面是DFS解法,个人认为没有BFS效率高
//DFS深度优先搜索就是一条道走到黑,然后再回来,比原值小就更新原值
//所以遍历次数可能更多一点,另外DFS使用了递归
#include<iostream>
#include<string.h>
using namespace std;
int a[10][10] = {0};
char str[10][10];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void dfs(int x,int y)
{
    for(int i=0;i<4;i++)
    {
        int m = x+dir[i][0];
        int n = y+dir[i][1];
        if(m>=0&&m<=9&&n>=0&&n<=9&&str[m][n]!='#')
        {
            if((a[m][n]==0)||(a[x][y]+1)<a[m][n])
            {
                a[m][n] = a[x][y]+1;
                dfs(m,n);
            }
        }
    }
       
}
int main()
{
//  freopen("input.txt","r",stdin);
    char c;
    while(~scanf("%c",&c))
    {
        str[0][0] = c;
        for(int i=1;i<10;i++)
        {
            scanf("%c",&c);
            str[0][i] = c;
        }
        getchar();
        for(int i=1;i<10;i++)
        {
            for(int j=0;j<10;j++)
            {
                scanf("%c",&c);
                str[i][j] = c;
            }
            getchar();
        }
        dfs(0,1);
        printf("%d\n",a[9][8]);
        memset(a,0,sizeof(a));
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值