输入一个二维数组表示迷宫,然后输入起始位置和要找到的位置,求其最短路径
地图样例
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
一个点可以向上 下 左 右 四个点继续走,所以得挨个走一下试试,走不动了就回退到上一个点,看看还能不能换个方向走,不行了就继续回退上一个点,以此类推,就是用bfs。为了方便,规定一个顺时针方向,即右下左上的顺序来走。
做这个题,可以直接写出四个方向的dfs,不过看上去很难看。。。。
以向右走为例
if(a[x][y+1]==0&&b[x][y+1]==0&&x>=1&&x<=n&&y+1>=1&&y+1<=m)
//if语句分别判断了右边的点是否能走,是否未走过和是否越界
{
b[x][y+1]=1;
dfs(x,y+1,step+1);
b[x][y+1]=0;//别忘了dfs后要变成0,要不然没法回退(回溯)了
}
也可以用一个方向数组直接表示下一步要走的位置,很简洁而且判断边界也很方便
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};//定义,也是按照右下左上的顺序
//比如向右走,x不变,y+1,所以是dx[0]=0,d[y]=1,tx=x+dx[0],ty=y+dy[0]
for(int k=0;k<=3;k++)
{
tx=x+dx[k];
ty=y+dy[k];
if(tx<1||tx>n||ty<1||ty>m) continue;//判断边界
if(a[tx][ty]==0&&b[tx][ty]==0)
{
b[tx][ty]=1;
dfs(tx,ty,step+1);
b[tx][ty]=0;//别忘了dfs后要变成0,要不然没法回退(回溯)了
}
}
啊哈算法上是这样给的方向数组。个人觉得不好理解,所以还是用两个数组吧
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
for(k=0;k<=3;k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
}
完整代码如下
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int a[100][100],b[100][100];//c++不让用map做变量名字......
int startx,starty,endx,endy;
int n,m;
int v=999999;//c++不让用min做变量名字......
void dfs(int x,int y,int step)
{
int tx,ty;
int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
if(x==endx&&y==endy)
{
if(step<v)//判断是不是最小的路径
{
v=step;
return;
}
}
for(int k=0;k<=3;k++)
{
tx=x+dx[k];
ty=y+dy[k];
if(tx<1||tx>n||ty<1||ty>m) continue;
if(a[tx][ty]==0&&b[tx][ty]==0)
{
b[tx][ty]=1;
dfs(tx,ty,step+1);
b[tx][ty]=0;//别忘了dfs后要变成0,要不然没法回退(回溯)了
}
}
return;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
cin>>startx>>starty;
cin>>endx>>endy;
b[startx][starty]=1;//起始位置先标记上,表示已经走过了
dfs(startx,starty,0);
cout<<"从"<<startx<<","<<starty<<"到"<<endx<<","<<endy<<endl;
cout<<"最短路径为"<<v;
return 0;
}