给定一个nm大小的迷宫,其中代表不可通过的墙壁,而“.”代表平地,S表示起点,T代表终点。移动过程中,如果当前位置为(x,y)(下标从0开始), 且每次只能前往上下左右四个位置的平地,求从起点S到达终点T的最少步数。
代码
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int maxn = 100;
struct node {
int x, y;//位置为(x,y)
int step;//step为从起点S到该位置的最少步数(即层数)
} S, T, Node;//分别代表起点,终点,临时节点
int n, m;//行列数
char maze[maxn][maxn];//迷宫信息
bool inq[maxn][maxn] = {false};//记录位置(x,y)是否已经入队
int X[4] = {0, 0, 1, -1};//增量数组
int Y[4] = {1, -1, 0, 0};
bool test(int x, int y) {//检测位置(x,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++) {//循环4次,得到四个相邻位置
int newX = top.x + X[i];
int newY = top.y + Y[i];
if (test(newX, newY)) {//位置(newX,newY)有效
Node.x = newX;
Node.y = newY;
Node.step = top.step + 1;//Node层数为top的层数加一
q.push(Node);//将结点Node加入队列
inq[newX][newY] = true;//设置位置(newX,newY)已入过队
}
}
}
return -1;//无法达到终点时返回-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;//初始化起点的层数为0,即S到S的最少步数为0
printf("%d\n", BFS());
return 0;
}