zoukankan      html  css  js  c++  java
  • 【洛谷】P1443 马的遍历

    题目:https://www.luogu.org/problemnew/show/P1443

    简单的BFS模板题——因为我写出来了。

    分析过程:

    n*m矩阵,用二维数组

    数据不大,二维数组稳了

    先把二维数组初始化为-1,马的坐标,即起点的坐标再设为0

    接着开始遍历——8个方向(下过中国象棋的大牛应该不陌生)

    设一个结构,储存落点的位置与所走的步数,每走一次就记录一次

    此时,还要判断落点是否还是-1,这样就可以避免重复

    本来这样就可以AC了,但此题有个陷阱就是:

    输出格式:

    一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)

    所以,要在输出上花点心思......(其实是要注意审题)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<queue>
     5 #define MAXN 402
     6 using namespace std;
     7 
     8 int ans[MAXN][MAXN];
     9 int n, m, n_b, m_b;
    10 int run_x[] = { 1, 1, 2, 2, -1, -1, -2, -2 };
    11 int run_y[] = { 2, -2, 1, -1, 2, -2, 1, -1 };
    12 
    13 struct node{
    14     int x, y;
    15     int step;
    16 };
    17 
    18 queue<node> q;
    19 
    20 void bfs(){
    21     node a;
    22     a.x = n_b;
    23     a.y = m_b;
    24     a.step = 0;
    25     ans[a.x][a.y] = a.step;
    26     q.push(a);
    27 
    28     while(!q.empty()){
    29         node b = q.front();
    30         node c;
    31         q.pop();
    32         for(int i = 0; i < 8; i++){
    33             c.x = b.x + run_x[i];
    34             c.y = b.y + run_y[i];
    35             if(0 < c.x && c.x <= n && 0 < c.y && c.y <= m 
    36     && ans[c.x][c.y] == -1){
    37                 c.step = b.step + 1;
    38                 ans[c.x][c.y] = c.step;
    39                 q.push(c);
    40             }
    41         }
    42     }
    43 }
    44 
    45 int main()
    46 {
    47     while(cin >> n >> m >> n_b >> m_b){
    48         memset(ans, -1, sizeof(ans));
    49         bfs();
    50         for(int i = 1; i <= n; i++){
    51             for(int j = 1; j <= m; j++){
    52                 printf("%-5d", ans[i][j]);
    53             }
    54             cout << endl;
    55         }
    56     }
    57     return 0;
    58 }

    下面说说我对BFS的理解

    BFS与DFS有个很相似的地方:对于所有情况,它们都做着相同的行为来遍历完所有情况。

    所以,BFS里肯定有一个“核心循环”(这里指对于每个方法路径的遍历),然后再判断下一位置是否还满足条件。

    如:

    for(int i = 0; i < 8; i++){
                c.x = b.x + run_x[i];
                c.y = b.y + run_y[i];
                if(0 < c.x && c.x <= n && 0 < c.y && c.y <= m 
          && ans[c.x][c.y] == -1){ c.step = b.step + 1; ans[c.x][c.y] = c.step; q.push(c); } }

    这里的循环是对马的8个方向的遍历,接着if语句是判断马跳下一步后是否还在棋盘上或者是否已经来过。

    虽然我做过的题不多,但做过的题都有这种“核心循环”,所以就特意画出来做了个笔记。

    嘻嘻,说了这么多好像还云里雾里的感觉。

    不知是不是,感觉学习算法还是要抓住那类算法的特性去理解,这样学起来就会更轻松。

    有点理解师兄所说的:只要思维理解了,代码的实现就不是问题了。

  • 相关阅读:
    MonoBehaviour.FixedUpdate 固定更新
    Gizmos 辅助线框
    Quaternion 四元数
    Object.Instantiate 实例
    c语言描述的静态查找表
    c语言描述的二叉树的基本操作(层序遍历,递归,非递归遍历)
    c语言描述的链队列的基本操作
    c语言描述的双向链表的基本操作
    c语言描述的简单选择排序
    c语言描述的二分插入排序法
  • 原文地址:https://www.cnblogs.com/Ayanowww/p/10680309.html
Copyright © 2011-2022 走看看