这是一道较为规整的BFS,代码有点长
Maze Master 题址
题目解释:就是有一个长为H,宽为W的二维表,全部都是’.‘或’#’。你任意从一个‘.’走到另一个’.’(不可以斜着),在所有的路中,最长的那条是多少?
宏观思路:在主函数中枚举每一组起、止点,记录下他们的行列坐标,以此来做宽搜。宽搜返回来的值,还要比一下max。
宽搜很好做,用queue队列就OK了
配合代码讲一下:
struct pos{ //结构体,行列号和步数(值)
int x;
int y;
int step;
};
pos make_pos(int a,int b,int c)
{
pos ret; //打包用的
ret.x=a;
ret.y=b;
ret.step=c;
return ret;
}
for(int i1=1;i1<=n;++i1) //枚举开头的行坐标
for(int j1=1;j1<=m;++j1)//枚举开头的列坐标
{
if(a[i1][j1]=='#')//如果当前格子是#,那就继续枚举
continue;
for(int i2=1;i2<=n;i2++) //枚举结尾的行坐标
for(int j2=1;j2<=m;j2++)//枚举结尾的列坐标
{
if(a[i2][j2]=='#')
continue;
if(i1==i2&&j1==j2)//如果开头和结尾是同一个点,那么重来
continue;
maxv=max(maxv,bfs(i1,j1,i2,j2));
}
}
int bfs(int sx,int sy,int ex,int ey)
// sx=start.x 起始点的行坐标 sy=start.y 起始点的列坐标 ex ey 同理
定义一个布尔型的vis[]数组,用来判重 false表示没来过,可以过来;true表示已来过,不能再来
while(!q.empty())
{
pos fr=q.front();//拿出队首
q.pop();//队首出队
if(fr.x==ex&&fr.y==ey)//如果当前的行列坐标,和结尾的坐标一样,说明已经结束
return fr.step;//返回值
for(int i=0;i<4;i++)//位移增量,无需解释
{
int nx=fr.x+dx[i];
int ny=fr.y+dy[i];
if(vis[nx][ny])//如果已经来过这个点,就重新探索
continue;
vis[nx][ny]=true;//如果没来过这个点,那就来一下,把他设成true
pos newpo=make_pos(nx,ny,fr.step+1);//打包一下,记录行列号和值
q.push(newpo);//入队
}
下面贴一下AC代码:
#include <bits/stdc++.h>
using namespace std;
char a[22][22]; //行列放大两个,防止出圈
int n,m;
struct pos{
int x;
int y;
int step;
};
pos make_pos(int a,int b,int c)
{
pos ret;
ret.x=a;
ret.y=b;
ret.step=c;
return ret;
}
int bfs(int sx,int sy,int ex,int ey)
{
bool vis[n+2][m+2];
for(int i=0;i<=n+1;i++)
for(int j=0;j<=m+1;j++)
if(a[i][j]=='#') //把墙壁‘#’,设为true表示不能来
vis[i][j]=true;
else vis[i][j]=false;
queue<pos> q;
q.push(make_pos(sx,sy,0));//起点的行列号先入队
vis[sx][sy]=true;//起点设成已来过
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
while(!q.empty())
{
pos fr=q.front();
q.pop();
if(fr.x==ex&&fr.y==ey)
return fr.step;
for(int i=0;i<4;i++)
{
int nx=fr.x+dx[i];
int ny=fr.y+dy[i];
if(vis[nx][ny])
continue;
vis[nx][ny]=true;
pos newpo=make_pos(nx,ny,fr.step+1);
q.push(newpo);
}
}
}
int main()
{
for(int i=0;i<22;i++)
for(int j=0;j<22;j++)
a[i][j]='#';
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
int maxv=0;
for(int i1=1;i1<=n;++i1)
for(int j1=1;j1<=m;++j1)
{
if(a[i1][j1]=='#')
continue;
for(int i2=1;i2<=n;i2++)
for(int j2=1;j2<=m;j2++)
{
if(a[i2][j2]=='#')
continue;
if(i1==i2&&j1==j2)
continue;
maxv=max(maxv,bfs(i1,j1,i2,j2));
}
}
cout<<maxv<<endl;
return 0;
}
该博客详细介绍了Atcoder151 D-Maze Master问题的解决方案,强调这是一道使用宽度优先搜索(BFS)的典型题目。博主分享了AC代码,并解释了如何通过枚举起点和终点,利用队列进行宽搜,以找到最长路径。
1140

被折叠的 条评论
为什么被折叠?



