BFS走迷宫

又来走迷宫了

在这里插入图片描述
上次用了DFS来走迷宫,嘻嘻今天学了BFS也来走一遍。
在这里插入图片描述
1.题目
一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行。同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。如果起点或者终点有一个不能通行(为#),则看成无法办到。

Input
第1行是测试数据的组数k,后面跟着k组输入。每组测试数据的第1行是一个正整数n (1 <= n <= 100),表示迷宫的规模是n * n的。接下来是一个n * n的矩阵,矩阵中的元素为.或者#。再接下来一行是4个整数ha, la, hb, lb,描述A处在第ha行, 第la列,B处在第hb行, 第lb列。注意到ha, la, hb, lb全部是从0开始计数的。

Output
k行,每行输出对应一个输入。能办到则输出“YES”,否则输出“NO”。

题意:题目老长了,简而言之就是**"#“是墙不能走,”."是路可以走**,写个程序判断我们是否能从起点走到终点

2.思路:
其实和dfs差不多,区别在于dfs是从七点开始盲选一条路一直往下走,而bfs是根据层间关系进行逐层搜索,相当于多条路一起搜索(有点分身那味儿)。

在这里插入图片描述
程序重点在于,不同于dfs通过递归来实现搜素,bfs是通过队列来实现的,所以在搜索过程中要注意queue的使用。每当搜索到可以走下去的节点时将节点放入到queue中,进行下一层的搜索。
详细解释在代码里面写啦~

3.代码实现

#include<bits/stdc++.h>
using namespace std;

const int N =105;
int n,k;
char g[N][N];//存图
int ha,la,hb,lb;//起点终点
bool ok=true;//检查是否到了终点
int xd[4]={-1,1,0,0};//四个方位变化
int yd[4]={0,0,-1,1};
bool vis[N][N];//标记是否为走过点
struct node{//记录坐标
    int x,y;
};
void bfs();

int main(){
    scanf("%d",&k);//输入次数
    while(k--){
        memset(vis,0,sizeof vis);//初始化
        ok=false;
    
        scanf("%d",&n);//图的大小
        for(int i=0;i<n;i++)
            scanf("%s",g[i]);//输入图
        scanf("%d%d%d%d",&ha,&la,&hb,&lb);//输入起点终点
        
        if(g[ha][la]=='#'||g[hb][lb]=='#'){//判断起点或终点是否为墙
            printf("NO\n");
            continue;
        }
       bfs();//开始搜索
       if(ok)//结果打印
            printf("YES\n");
       else
            printf("NO\n");
    }
	return 0;
}

void bfs(){
	queue<node>q;//存储坐标,比数组慢一点
    q.push({ha,la});//放入起始点
    while(q.size()){//终止条件,队列中已经没有元素,即搜索完毕
        node t=q.front();//得到队头元素
        q.pop();//弹出队头元素
        int x=t.x;//得到相应的坐标
        int y=t.y;
        
        if(x==hb&&y==lb){//判断是否到达终点
            ok=true;
            return;
        }
        for(int i=0;i<4;i++){//未到终点,继续搜索
			int xx=x+xd[i];
            int yy=y+yd[i];
       
            if(xx<0||xx>=n||yy<0||yy>=n)//判断是否满足搜索条件
                continue;
            if(g[xx][yy]=='#')
                continue;
            if(vis[xx][yy]==true)
                continue;
            
            vis[xx][yy]=true;//标记已搜索
            q.push({xx,yy});//放入下一层坐标
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值