bfs就是所谓的广度搜索( Breadth first search),这种算法旨在解决最优问题,如最小时间,最快路径之类的。实际上dfs(深度优先搜索)也是可以解决此类问题(这个可以参考下一篇),但是鉴于题目的空间和时间的限制,你不得不选择bfs(深搜同样也能解决最优问题,但是他是将所有的结果都找出来,那么时间上你已经gg了)
简单来说,这个算法就是将地图上能走的点走一遍,找出最优的解。步骤的话,就是创建2维数组,作为地图,然后找到起点和终点,从起点开始,输入每个点。然后进行判断。这个一点是不是符合要求,然后标记这个点已经走过了。
(为了明显区分两种算法的区别,我这里使用结构体的知识来完成这个算法)
关于这个算法,根据我上面所说,你可以分成4部分来完成。第一部分当然是最简单的读入地图
int a[100][100],v[100][100];//a是地图。v是标记地图有没有走过
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
地图可能是字符也可能是数字(当然在这里i=0,i<n,也是可以的)
所以也可以这样输入(下面那个是解决字符串情况的)
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",a[i])
当然,如果,你不是很确定自己的地图输入是否有问题的话,你可以选择输出,去检测
然后 就是去寻找终点和起点,然后记录下来。当然,有些题目是会让你直接输入终点和起点的。。但是大部分还是要自己找。
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(a[i][j]=='@')
{
startx=i;
starty=j;
}
if(a[i][j]=='*')
{
p=i;
q=j;
a[i][j]='.';
}
}
这里有个细节就是,如果你找到终点的话,那么要将终点变成能走的地区,否则,你最后的步数会少1
因为,终点他是不会走的。(正常的代码都是找到终点后就直接结束,当然,你也可以选择在最后在加1上去。效果也是一样的)
然后就是最重要的dfs部分了。
struct point
{ int x;
int y;
int step;};
queue<point>r;//申请队列
int dx[4]={0,1,0,-1};//顺时针右 下左上
int dy[4]={1,0,-1,0};
你要先定义结构体。dx和dy的话就作为方向。dfs的话要那么逆时针要么顺时针走,
point start;
start.x=startx; //start是起点
start.y=starty;
start.step=0;
r.push(start);//入队
v[startx][starty]=1;
int flag =0;//这个是用来判断能不能到终点的,如果能就是1
while(!r.empty())//如果队列不为空的话,那么久执行
{
int x=r.front().x;
int y=r.front().y;
if(x==p&&y==q) {
flag=1;
printf("%d",r.front().step);
}
for(int k=0;k<=3;k++)//这里是3个方向,
{ int tx,ty;
tx=x+dx[k];
ty=y+dy[k];
if(a[tx][ty]==1&&v[tx][ty]==0)//是空地并且未访问
{ //入队
point temp;
temp.x=tx;
temp.y=ty;
temp.step=r.front().step+1;
r.push(temp);
v[tx][ty]=1;
}
}
r.pop();//出队
}
if(flag==0)
printf("no");
return 0;
}
这里还要注意的就是,如果你是处理守卫问题的话(即打败一个守卫会花费1一个时间单位),会遇到一个问题,这是路程最短,
但不是时间最短。那么你需要在前面加一个判断,如果是是守卫的话,时间加1
,但是不标记守卫走过。然后将守卫变成能走的路即可
完整的代码是这样的:
//这个代码旨在解决一个出口,一个起点,找到最小的路径的问题
#include<bits/stdc++.h>
using namespace std;
int a[100][100],v[100][100];//a是地图。v是标记地图有没有走过
struct point
{
int x;
int y;
int step;
};
queue<point>r;//申请队列
int dx[4]={0,1,0,-1};//顺时针右 下左上
int dy[4]={1,0,-1,0};
int main()
{
int n,m,startx,starty,p,q;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
scanf("%d%d%d%d",&startx,&starty,&p,&q);
//bfs
point start;
start.x=startx;
start.y=starty;
start.step=0;
r.push(start);//入队
v[startx][starty]=1;
int flag =0;
while(!r.empty())
{
int x=r.front().x;
int y=r.front().y;
if(x==p&&y==q)
{
flag=1;
printf("%d",r.front().step);
}
for(int k=0;k<=3;k++)
{
int tx,ty;
tx=x+dx[k];
ty=y+dy[k];
if(a[tx][ty]==1&&v[tx][ty]==0)//是空地并且未访问
{
//入队
point temp;
temp.x=tx;
temp.y=ty;
temp.step=r.front().step+1;
r.push(temp);
v[tx][ty]=1;
}
}
r.pop();//出队
}
if(flag==0)
printf("no");
return 0;
}