• luoguP1443马的遍历


    题目链接

    本题主要思路是搜索

    刚开始想写bfs,写着写着就写假了写成了dfs

    dfs会TLE成80分

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int N = 410;
    
    int n, m;
    int ans[N][N];
    bool book[N][N];
    int dx[8] = {2, 1, 1, 2, -1, -1, -2, -2};
    int dy[8] = {1, -2, 2, -1, 2, -2, 1, -1};
    
    void bfs(int x, int y, int d) {
        if(x < 1 || y < 1 || x > n || y > m || (ans[x][y] != -1 && ans[x][y] <= d)) return;
        // q.push({x, y});
        book[x][y] = 1;
        if(ans[x][y] != -1)ans[x][y] = min(ans[x][y], d);
        else ans[x][y] = d;
        for(int i = 0 ; i < 8 ; i ++) {
            bfs(x + dx[i], y + dy[i], d + 1);
        }
        return;
    }
    void print() {
        for(int i = 1; i <= n ; i ++) {
            for(int j = 1; j <= m ; j ++) {
                printf("%-5d", ans[i][j]);
            }
            printf("
    ");
        }
    }
    
    int main () {
        int a, b;
        scanf("%d%d%d%d", &n, &m, &a, &b);
        for(int i = 1; i <= n ; i ++) {
            for(int j = 1; j <= m ; j ++) {
                ans[i][j] = -1;
            } 
        }
        bfs(a, b, 0);
        print();
        return 0;
    }
    

    而且这个里面的book数组没有用到


    值得一提的是:这道题的输入输出非常重要

    题目要求左对齐,宽五格

    我:printf("%d(+五个空格)", ...); --> 0分

    看了看题目是四个空格,于是把五个空格改成了四个空格,20分。

    看了题解是printf("%-5d", ...); 80分。(以前wa的点全都ac,剩下的就是tle了)

    真就离谱。


    接下来开始想正解

    bfs,肯定要用到队列。

    • 先将出初始状态入队,枚举这个状态所有可能的状态,修改答案。

    • 将当前状态出队,枚举到的可能状态入队,然后继续枚举接下来的状态。

    • 如果枚举到了一个状态,我们先前已经枚举过了,现在就不用枚举了,直接continue即可。因为原来枚举到过肯定是之前已经走到过,如果再枚举他,标记的值肯定没有先前的值优,所以不必枚举。
      这也是广度优先搜索(宽搜bfs)的一条重要性质

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int N = 410;
    
    int n, m;
    int ans[N][N];
    bool book[N][N];
    int dx[8] = {2, 1, 1, 2, -1, -1, -2, -2};
    int dy[8] = {1, -2, 2, -1, 2, -2, 1, -1};
    
    typedef pair<int, int> PII;
    void bfs(int x, int y, int d) {
        ans[x][y] = d;
        book[x][y] = 1;
        queue<PII> q;
        q.push({x, y});
        while(q.size()) {
            PII top = q.front();
            q.pop();
            int fx = top.first, fy = top.second;
            for(int i = 0 ; i < 8 ; i ++) {
                int nx = fx + dx[i], ny = fy + dy[i];
                if(nx < 1 || ny < 1 || nx > n || ny > m || book[nx][ny]) continue;
                top.first = nx, top.second = ny;
                q.push(top);
                book[nx][ny] = 1;
                ans[nx][ny] = ans[fx][fy] + 1;
            }
        }
    }
    void print() {
        for(int i = 1; i <= n ; i ++) {
            for(int j = 1; j <= m ; j ++) {
                printf("%-5d", ans[i][j]);
            }
            printf("
    ");
        }
    }
    
    int main () {
        int a, b;
        scanf("%d%d%d%d", &n, &m, &a, &b);
        for(int i = 1; i <= n ; i ++) {
            for(int j = 1; j <= m ; j ++) {
                ans[i][j] = -1;
            } 
        }
        bfs(a, b, 0);
        print();
        return 0;
    }
    

    AC代码简单易懂。

    dx,dy的偏移量在这里也很妙。

  • 相关阅读:
    POJ2778 DNA Sequence AC自动机上dp
    codeforces732F Tourist Reform 边双联通分量
    codeforces786B Legacy 线段树优化建图
    洛谷P3588 PUS 线段树优化建图
    codeforces1301D Time to Run 模拟
    codeforces1303B National Project 二分或直接计算
    codeforces1303C Perfect Keyboard 模拟或判断欧拉路
    codeforces1303D Fill The Bag 二进制应用+贪心
    python之路——使用python操作mysql数据库
    python之路——mysql索引原理
  • 原文地址:https://www.cnblogs.com/sjzez-llb/p/13810587.html
Copyright © 2020-2023  润新知