又来走迷宫了
上次用了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});//放入下一层坐标
}
}
}