题目描述:*号是墙壁,无法通过,S是起点,T是终点,要求求S到T的最短距离

  1. 一开始没想明白怎么样是最短,这里应该是第一次遍历到的路径就是最短的,因此不需要有其他特殊操作
  2. inq数组是记录结点是否已经入过队,而不是是否被访问,因为有可能该坐标已入队但未被访问,在访问其他结点的时候多次入队,导致计算量大大增加。
  3. 这题和01小岛问题很像,模版都几乎一摸一样,可以参考一下再看一下,必须要定义的有这几个
    1. 结构体中必有x,y,可能还有其他根据题目设置的参数,然后还有个临时结点node
    2. 输入矩阵matrix、扫描矩阵inq
    3. 增量数组X、Y
    4. 矩阵大小参数m,n
    5. 判断合法xy的函数judge
    6. BFS函数
      1. 初始化起点,可以是全局变量,也可以是函数参数
      2. 将该结点押入队列,并设置inq矩阵该结点已访问
      3. 当队列不为空时,出队列,(判断是否符合退出条件,符合则返回)
      4. 使用增量矩阵开始扫描周围符合条件的结点,然后将临时结点参数更新,inq置为true,再入队列
    7. main函数中,输入矩阵初始化
      1. 如果是字符串需要使用getchar()吸收换行符,再在每一行末尾加入’\0’
    8. 根据题目要求,使用BFS得到结果
  4. 这题与小岛问题不一样的地方,第一个是这道题的输入为字符串,另外一个是小岛问题多次调用了BFS函数

代码

  1. #include<vector>
  2. #include<iostream>
  3. #include<queue>
  4. #include<algorithm>
  5. using namespace std;
  6. const int maxn = 10010;
  7. struct Node{
  8. int x, y;
  9. int step;
  10. }S, T, node;
  11. int n, m;
  12. int matrix[maxn][maxn];
  13. bool inq[maxn][maxn] = {false};
  14. int X[4] = {0, 0, 1, -1};
  15. int Y[4] = {1, -1, 0, 0};
  16. bool judge(int x, int y){
  17. if(x >= n || y >= m || x < 0 || y > 0) return false;
  18. if(matrix[x][y] == '*') return false;
  19. if(inq[x][y] == true) return false;
  20. return true;
  21. }
  22. int BFS(){
  23. queue<Node> q;
  24. q.push(S);
  25. inq[S.x][S.y] = true;
  26. while(!q.empty()){
  27. Node top = q.front();
  28. q.pop();
  29. if(top.x == T.x && top.y == T.y) return top.step;
  30. for(int i = 0; i < 4; i++){
  31. int newx = top.x + X[i];
  32. int newy = top.y + Y[i];
  33. if(judge(newx, newy)){
  34. inq[newx][newy] = true;
  35. node.x = newx, node.y = newy, node.step = top.step + 1;
  36. q.push(node);
  37. }
  38. }
  39. }
  40. }
  41. int main(){
  42. scanf("%d%d", &n, &m);
  43. for(int i = 0; i < n; i++){
  44. getchar();
  45. for(int j = 0; j < m; j++){
  46. matrix[i][j] = getchar();
  47. }
  48. matrix[i][m+1] = '\0';
  49. }
  50. scanf("%d%d%d%d", &S.x, &S.y, &T.x, &T.y);
  51. S.step = 0;
  52. printf("%d",BFS);
  53. return 0;
  54. }