问题描述:
emsp;给定一个n*m大小的迷宫,其中 * 代表不可通过的墙壁,.代表平底,S表示起点,T代表终点。移动过程中,如果当前位置是(x,y)(下标从0开始),且每次只能前往上下左右(x+1,y)(x-1,y),(x,y+1),(x,y-1)四个位置的平地,求S到T的最小步数。
.....
.*.*.
.*S*.
.***.
...T*
上述案例中,S为(2,2),T为(4,3)
思路:
由于求的是最小步数,而BFS是通过层次的顺序来遍历的,因此可以从S开始记录遍历的层数,那么在到达T时层数就是求解出来的最小步数。
代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 100;
struct node{
int x,y;//位置
int step;//到终点的最少步数,即层数
}S,T,Node;
int n,m;//行和列
char maze[maxn][maxn];//迷宫信息
bool inq[maxn][maxn] = {false};//记录是否已经入队
int X[4]={0,0,1,-1};
int Y[4]={1,-1,0,0};
//检测位置(x,y)是否有效
bool test(int x, int y){
if(x >= n || x < 0 || y >= m || y < 0)
return false;
if(maze[x][y]=='*')
return false;
if(inq[x][y]==true)
return false;
return true;
}
int BFS(){
queue<node> q;
q.push(S);
while(!q.empty()){
node top = q.front();//取出队首元素
q.pop();
if(top.x == T.x && top.y == T.y)
return top.step;//已经到达终点
for(int i = 0 ; i < 4 ; i++){
int newX = top.x + X[i];
int newY = top.y + Y[i];
if(test(newX,newY)){
//如果位置有效
Node.x = newX;
Node.y = newY;
Node.step = top.step+1;
q.push(Node);
inq[newX][newY] = true;
}
}
}
return -1;
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 0 ; i < n ; i++){
getchar();//过滤掉每行的换行字符
for(int j = 0 ; j < m ; j++){
maze[i][j] = getchar();
}
maze[i][m+1] = '\0';
}
scanf("%d%d%d%d",&S.x,&S.y,&T.x,&T.y);
S.step = 0;
printf("%d\n",BFS());
return 0;
}