题目描述
给定一个n*m大小的迷宫,其中“ * ”代表不可通过的墙壁,而“ . ”代表平地,S表示起点,T代表终点。移动过程中,如果当前位置是(x,y)(下标从0开始),且每次只能前往上下左右(x,y+1)、(x,y-1)、(x-1,y)、(x+1,y)四个位置的平地,求从起点S到达终点T的最少步数。
输入数据:
5 5 // 表示5行5列
. . . . . //迷宫信息
. * . * .
. * S * .
. * * * .
. . . T *
2 2 4 3 // 起点S的坐标与终点T的坐标
解题思路:
在本题中,由于求的是最少步数,而BFS是通过层次的顺序来遍历的,因此可以从起点S开始计数遍历的层数,那么在到达终点T时的层数就是需要求解的起点S到达终点T的最少步数。
使用struct结构体来保存当前结点所在的行和列,以及当前的层次
struct Node
{
int x, y;
int step;//层数
Node(int x, int y) {
this->x = x;
this->y = y;
this->step = 0;
}
};
下面为实现代码:
#include <iostream>
using namespace std;
#include <vector>
#include <string>
#include <queue>
struct Node
{
int x, y;
int step;//层数
Node(int x, int y) {
this->x = x;
this->y = y;
this->step = 0;
}
};
//当前坐标的四周
const int X[] = { 0, 0, -1, 1 };
const int Y[] = { -1, 1, 0, 0 };
//判断当前位置是否可以访问
bool judge(vector< vector<char> >& matrix, int rows, int cols, int x, int y, bool* visited) {
//判断越界
if (x < 0 || x >= rows || y < 0 || y >= cols)
{
return false;
}
if (matrix[x][y] == '*' || visited[x * cols + y])
{
return false;
}
return true;
}
//************************************
// Method: bfs 求起点到终点的最短步数
// FullName: bfs
// Access: public
// Returns: int
// Qualifier:
// Parameter: vector< vector<char> > & matrix 给定矩阵
// Parameter: int rows 给定矩阵的总行数
// Parameter: int cols 给定矩阵的总列数
// Parameter: int x 当前位置所在的行
// Parameter: int y 当前位置所在的列
// Parameter: int tx 终点所在的行
// Parameter: int ty 终点所在的列
// Parameter: bool * visited 当前坐标是否已经入过队
//************************************
int bfs(vector< vector<char> >& matrix, int rows, int cols, int x, int y, int tx, int ty, bool* visited) {
//下面为bfs的模板
queue<Node> q;
Node node(x, y);
q.push(node);
while (!q.empty())
{
Node top = q.front();
q.pop();
if (top.x == tx && top.y == ty)
{
return top.step;
}
for (int i = 0; i < 4; i++)
{
int newX = top.x + X[i];
int newY = top.y + Y[i];
if (judge(matrix,rows,cols,newX,newY,visited))//遍历四个方向
{
node.x = newX;
node.y = newY;
node.step = top.step + 1;//层数+1
q.push(node);
visited[cols * newX + newY] = true;
}
}
}
return -1;// 无法到达终点时返回-1
}
//将 str 转为 char 数组
vector<char> strToVector(string str) {
vector<char> res;
for (int i = 0; i < str.size();i++)
{
if (str[i] != ' ')
{
res.push_back(str[i]);
}
}
return res;
}
//求起点到达终点的最少步数
int main() {
vector< vector<char> > matrix;
int rows, cols;
cin >> rows >> cols;
getchar();
string str;
for (int i = 0;i < rows;i++)
{
getline(cin, str);
matrix.push_back(strToVector(str));
}
int x, y, tx, ty;
cin >> x >> y >> tx >> ty;
bool* visited = new bool[rows * cols];//表示当前结点是否已经入过队
memset(visited, false, rows * cols);
cout << bfs(matrix, rows, cols, x, y, tx, ty, visited) << endl;
system("pause");
return 0;
}