今天,终于熟练掌握如何使用广搜(bfs)来解决问题
那么,咱们就从一个实例出发,来探讨一下广搜的魅力
link.
我将该题命名为:小白鼠吃奶酪bfs
简单说一下:就是定义一个结构体储存当前坐标和走的步数,再利用队列,一个一个的压进队列,在对第一个进行判断是否是我们所要找的“奶酪”。
接下来详细说一下(代码的实现):
首先定义t组数据,r行c列,方向数组xx,yy,然后是map字符数组,v拜访数组,结构体node记录坐标和步数。
接下来就是bfs,由于我们的目的是找出最少步数,因此需要返回一个int型数据,因此我们定义函数类型为int,传入四个参数(因为每组数据的起始坐标和终止坐标都不一样)nx,ny,ex,ey,
接下来定义一个队列,定义两个node型变量now,next,对now进行初始化,拜访数组中该坐标所对应的点拜访过置1,将now压入队列里,当队列不为空时,将队列里的第一个赋值给now,将第一个弹出,判断第一个是否满足要求,若满足则返回now的步数;
接下来,要进行上下左右的搜索,运用方向数组和循环,接着判断新坐标是否越界是否为==‘#’==是否拜访过,若满足要求,将新坐标的拜访坐标置1,让next节点的坐标存储新坐标,同时让next的步数等于now步数的+1,再把next节点压进队列里,在进行循环看这一层是否还有满足的,只要满足就压进去,
直到你所访问的第一个节点的坐标为最终坐标则返回最终坐标的步数,若最终队列空了,那就是没有访问到,则返回0(为啥返回0呢?因为主函数中用if语句只要返回的数不为0就是找到了,否则就是没找到因此在函数中没找到要返回0)
在主函数中再输入map字符数组时,同时寻找起始坐标和终止坐标,记得要在bfs执行前,对拜访数组进行置0操作.
感谢大家的欣赏,为自己点个赞,送上本人代码
#include
#include
#include
using namespace std;
int t,r,c,xx[]={0,1,0,-1},yy[]={1,0,-1,0};
char map[201][201];
int v[201][201];
struct node{
int x,y,step;
};
int bfs(int nx,int ny,int ex,int ey)
{
queue<node> q;
node now,next;
now.x=nx;
now.y=ny;
now.step=0;
v[now.x][now.y]=1;
q.push(now);
while(!q.empty())
{
now=q.front();
q.pop();
for(int i=0;i<4;i++)
{
if(now.x==ex&&now.y==ey)
return now.step;
int dx=now.x+xx[i];
int dy=now.y+yy[i];
if(dx>=0&&dx<r&&dy>=0&&dy<c&&v[dx][dy]==0&&map[dx][dy]!='#')
{
v[dx][dy]=1;
next.x=dx;
next.y=dy;
next.step=now.step+1;
q.push(next);
}
}
}
return 0;
}
int main()
{
int i,j,nx,ny,ex,ey;
cin>>t;
while(t--)
{
cin>>r>>c;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
cin>>map[i][j];
if(map[i][j]=='S')
{
nx=i;
ny=j;
}
if(map[i][j]=='E')
{
ex=i;
ey=j;
}
}
}
memset(v,0,sizeof(v));
int k=bfs(nx,ny,ex,ey);
if(k)
cout<<k<<endl;
else
cout<<"oop!"<<endl;
}
return 0;
}