zoukankan      html  css  js  c++  java
  • USACO06JAN The Grove

    题目传送门

    新技巧!


    了解了个新东西:虚拟射线法

    题目要求我们绕树林一圈,为了使我们的搜索能满足这个条件,可以任意找一棵树,在它的下方建一堵墙,将原图分为左右两半,搜索时不许过墙,最后把墙拆掉,将图的两部分合并就可以了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    #include <ctime>
    #define LL long long
    using namespace std;
    LL read() {
        LL k = 0; char c = getchar();
        while(c < '0' || c > '9')
            c = getchar();
        while(c >= '0' && c <= '9')
            k = k * 10 + c -48, c = getchar();
        return k;
    }
    char read_c() {
        char c = getchar();
        while(c != '.' && c != '*' && c  != 'X')
            c = getchar();
        return c;
    }
    int mapp[1010][1010];
    struct zzz {
        int x, y;
    }q[100010]; int h = 1, t;
    int fx[9] = {0, 1, 0, -1, 0, 1, 1, -1, -1},
        fy[9] = {0, 0, -1, 0, 1, 1, -1, 1, -1};
    int n, m;
    bool judge(int xx, int yy) {
        if(xx < 1 || xx > n || yy < 1 || yy > m) return 1;
        return 0;
    }
    int main() {
        //freopen("1.in", "r", stdin);
        n = read(), m = read();
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j) {
                char c = read_c();
                if(c == 'X') mapp[i][j] = -1;
                if(c == '*') q[++t].x = i, q[t].y = j, mapp[i][j] = 1;
            }
        srand(time(0));
        int rx = rand() % n + 1, ry = rand() % m + 1;
        while(!mapp[rx][ry]) rx = rand() % n + 1, ry = rand() % m + 1;
        for(int i = rx + 1; i <= n; ++i)	//建墙
            if(mapp[i][ry] != -1) mapp[i][ry] = -2;
        while(h <= t) {
            int x = q[h].x, y = q[h++].y;
            for(int i = 1; i <= 8; ++i) {
                int xx = x + fx[i], yy = y + fy[i];
                if(mapp[xx][yy] || judge(xx, yy)) continue;
                mapp[xx][yy] = mapp[x][y] + 1;
                q[++t].x = xx, q[t].y = yy;
            }
        }
        int ans = 2333;
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
                if(mapp[i][j] == -2) {	//拆墙+合并
                    for(int k = -1; k <= 1; ++k)
                        for(int o = -1; o <= 1; ++o) {
                            int xx1 = i + k, xx2 = i + o;
                            if(mapp[xx1][j-1] == -1 || mapp[xx2][j+1] == -1 || judge(xx1, j-1) || judge(xx2, j+1) || !mapp[xx1][j-1] || !mapp[xx2][j+1])
                                continue;
                            ans = min(ans, mapp[xx1][j-1] + mapp[xx2][j+1]);
                        }
                }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    如何找到bug(8): SequentialInputHandler::run()取数逻辑
    如何找到bug(7): 检查事例完整性的逻辑
    如何寻找bug(6)
    如何寻找bug(5)
    c++ : 静态成员函数
    c++:静态数据成员
    如何打开某一个包的debug
    如何寻找bug(4)
    如何找bug(3)
    Oracle学习系类篇(二)
  • 原文地址:https://www.cnblogs.com/morslin/p/11855234.html
Copyright © 2011-2022 走看看