• P1443 马的遍历


    一道队列广搜题

    此题使用队列实现,现将初始状态加入到空的队列当中;然后每次取出对首,找出队首所能转移到的状态,再将其压入队列;如此反复,这样就能保证一个状态在被访问的时候一定是采用的最短路径。

    广度优先搜索的一般形式

    这里是使用队列实现广度优先搜索的一般形式:

    Q.push(初始状态);//将初始状态入队
    while (!Q.empty()) {
      State u = Q.front();//取出对首
      Q.pop();//出队
      for (枚举所有可扩展状态) //找到u的所有可达状态v
        if (是合法的)  //v需要满足某些条件,如未访问过、未在队内等
          Q.push(v);//入队(同时可能需要维护某些必要信息)
    }
    

    就本题而言,先建立一个结构体数组用于存储扩展的节点。先让起点入队,然后在队列取状态逐个扩展。容易被证明每个点被扩展到时一定是最小步数。复杂度是O(mn)

    代码实现

    #include <cstdio>
    #include <queue>
    #include <cstring>
    #define maxn 310
    
    using namespace std;
    
    struct Node {
      int x, y;
    };
    
    queue<Node> Q;
    int ans[maxn][maxn];
    int walk[8][2] = {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}, };
    
    int main() {
      int n, m, sx, sy;
      memset(ans, -1, sizeof(ans));
      scanf("%d %d %d %d", &n, &m, &sx, &sy);
      Node tmp = {sx, sy};
      Q.push(tmp);
      ans[sx][sy] = 0;
      while(!Q.empty()) {
        Node u = Q.front();
        int ux = u.x, uy = u.y;
        Q.pop();
        for (int k = 0; k < 8; ++k) {
          int x = ux + walk[k][0];
          int y = uy + walk[k][1];
          int d = ans[ux][uy];
          if (x < 1 || x > n || y < 1 || y > m || ans[x][y] != -1) continue;
          ans[x][y] = d + 1;
          Node tmp = {x, y};
          Q.push(tmp);
        }
      }  
      for (int i = 1; i <= n; ++i, puts("")) {
        for (int j = 1; j <= m; ++j)
        printf("%-5d", ans[i][j]);
      }
      return 0;
    }
    
  • 相关阅读:
    营销运营中会遇到的名词及解释
    常用excel函数公式及操作示例
    opensuse安装pycharm
    Atom 基础使用
    git使用
    初学Python(第一课)
    django新手第一课
    浅谈session,cookie,sessionStorage,localStorage的区别及应用场景
    事件冒泡的应用
    django站点管理
  • 原文地址:https://www.cnblogs.com/Kyriech-Francis/p/Answer_P1143.html
Copyright © 2020-2023  润新知