题目描述:*号是墙壁,无法通过,S是起点,T是终点,要求求S到T的最短距离
- 一开始没想明白怎么样是最短,这里应该是第一次遍历到的路径就是最短的,因此不需要有其他特殊操作
- inq数组是记录结点是否已经入过队,而不是是否被访问,因为有可能该坐标已入队但未被访问,在访问其他结点的时候多次入队,导致计算量大大增加。
- 这题和01小岛问题很像,模版都几乎一摸一样,可以参考一下再看一下,必须要定义的有这几个
- 结构体中必有x,y,可能还有其他根据题目设置的参数,然后还有个临时结点node
- 输入矩阵matrix、扫描矩阵inq
- 增量数组X、Y
- 矩阵大小参数m,n
- 判断合法xy的函数judge
- BFS函数
- 初始化起点,可以是全局变量,也可以是函数参数
- 将该结点押入队列,并设置inq矩阵该结点已访问
- 当队列不为空时,出队列,(判断是否符合退出条件,符合则返回)
- 使用增量矩阵开始扫描周围符合条件的结点,然后将临时结点参数更新,inq置为true,再入队列
- main函数中,输入矩阵初始化
- 如果是字符串需要使用getchar()吸收换行符,再在每一行末尾加入’\0’
- 根据题目要求,使用BFS得到结果
- 这题与小岛问题不一样的地方,第一个是这道题的输入为字符串,另外一个是小岛问题多次调用了BFS函数
代码
#include<vector>#include<iostream>#include<queue>#include<algorithm>using namespace std;const int maxn = 10010;struct Node{int x, y;int step;}S, T, node;int n, m;int matrix[maxn][maxn];bool inq[maxn][maxn] = {false};int X[4] = {0, 0, 1, -1};int Y[4] = {1, -1, 0, 0};bool judge(int x, int y){if(x >= n || y >= m || x < 0 || y > 0) return false;if(matrix[x][y] == '*') return false;if(inq[x][y] == true) return false;return true;}int BFS(){queue<Node> q;q.push(S);inq[S.x][S.y] = true;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(judge(newx, newy)){inq[newx][newy] = true;node.x = newx, node.y = newy, node.step = top.step + 1;q.push(node);}}}}int main(){scanf("%d%d", &n, &m);for(int i = 0; i < n; i++){getchar();for(int j = 0; j < m; j++){matrix[i][j] = getchar();}matrix[i][m+1] = '\0';}scanf("%d%d%d%d", &S.x, &S.y, &T.x, &T.y);S.step = 0;printf("%d",BFS);return 0;}
