• Luogu P1519 穿越栅栏 Overfencing


    吐槽

    这搜索,真TMD恶心。我调了俩小时。。。。。。丧尽天良

    坑点

    • 从出口往里跳的时候只能挑一格。
    • 从别的格子跳往其他格子的时候只能跳两格
    • 跳两格的时候还必须判断中间隔过去的一格是不是空格
    • 输入格式也很恶心,在要求读空格的前提下好的办法只有gets,但是用gets会把两个整数后面的回车读进去。。

    思路

    从数据范围来看的话,从每个点都搜一遍最短距离是不现实的了。。当然不排除你写的很好看QwQ。我的想法是将两个出口找出来,然后跑两边BFS,每个点都维护一个距离的最小值

    要注意分类讨论从出口往别的格子跳和从普通格子跳往普通格子。跑的还挺快。空间也不大。我排在最优解的第二页QwQ

    代码

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    
    const int INF = 2147483647;
    
    using namespace std;
    
    int n, m, sx[3], sy[3], cnt, ans;
    char map[208][90];
    int dis[208][90];
    int dx[5] = {0, 2, 0, -2};
    int dy[5] = {2, 0, -2, 0};
    
    int rx[5] = {0, 1, 0, -1};
    int ry[5] = {1, 0, -1, 0};
    struct node {
        int x, y, sum;
    }temp, now;
    queue<node> Q;
    bool vis[208][90];
    
    inline void BFS(int num) {
        memset(vis, 0, sizeof(vis));
        while (!Q.empty()) Q.pop();
        vis[sx[num]][sy[num]] = 1;
        temp.sum = 0, temp.x = sx[num], temp.y = sy[num];
        Q.push(temp);
        while (!Q.empty()) {
            now = Q.front();
            int x = now.x, y = now.y, s = now.sum;
            Q.pop();
            dis[x][y] = min(s, dis[x][y]);
            for(int i=0; i<4; i++) {
                int xx = dx[i]+x, yy = dy[i]+y;
                int zx = rx[i]+x, zy = ry[i]+y;
                if(!vis[xx][yy] && map[xx][yy] == ' ' && xx <= 2*n+1 && xx > 0 && yy <= 2*m+1 && yy > 0 && map[zx][zy] == ' ' && (x != sx[num] || y != sy[num])) {
                    vis[xx][yy] = 1;
                    temp.x = xx, temp.y = yy, temp.sum = s+1;
                    Q.push(temp);
                }
                if(!vis[zx][zy] && map[zx][zy] == ' ' && x == sx[num] && y == sy[num] && zx <= 2*n+1 && zy <= 2*m+1 && zx > 0 && zy > 0) {
                    vis[zx][zy] = 1;
                    temp.x = zx, temp.y = zy, temp.sum = s+1;
                    Q.push(temp);
                }
            }
        }
    }
    
    int main() {
        scanf("%d%d", &m, &n);
        for(int i=1; i<=2*n+1; i++) {
            for(int j=1; j<=2*m+1; j++) {
                dis[i][j] = INF;
            }
        }
        gets(map[0]);
        for(int i=1; i<=2*n+1; i++) {
            gets(map[i]+1);
            for(int j=1; j<=2*m+1; j++) {
                if(i == 1 || j == 1 || i == 2*n+1 || j == 2*m+1)
                    if(map[i][j] == ' ') {
                        sx[++cnt] = i;
                        sy[cnt] = j;
                    }
            }
        }
        BFS(1);
        BFS(2);
        for(int i=1; i<=2*n+1; i++) {
            for(int j=1; j<=2*m+1; j++) {
                if(dis[i][j] != INF)
                    ans = max(ans, dis[i][j]);
            }
        }
        printf("%d", ans);
    }
  • 相关阅读:
    字典dict
    数组处理
    switch语句
    java基础复习2
    位运算
    内存中占用的字节
    java基础复习
    常用快捷键
    利用Typora设计博客的方式
    java数据结构-排序算法-堆算法
  • 原文地址:https://www.cnblogs.com/bljfy/p/9309688.html
Copyright © 2020-2023  润新知