• floodfill


    floodfill

    1.算法分析

    floodfill就是求出连通块的算法,一般可以采用dfs或者bfs,但是dfs容易爆栈,故而采用bfs为佳

    2. 例题

    acwing1097池塘计数
    一块N * M的土地,其中有'W'和'.'组成,'.'为土地,'W'为水,水的八个方向可以连在一起形成池塘,问一块土地上有多少个池塘?
    N,M~1e3

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int const N = 1e3 + 10;
    int n, m;
    char a[N][N];
    int st[N][N];
    queue<pair<int, int> > q;
    int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
    int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
    
    void bfs(int x, int y) {
        q.push({x, y});
        st[x][y] = 1;
        while (q.size()) {
            auto t = q.front();
            q.pop();
            
            for (int i = 0; i < 8; ++i) {
                int next_x = t.first + dx[i], next_y = t.second + dy[i];
                if (next_x < 0 || next_x > n - 1 || next_y < 0 || next_y > m - 1) continue;
                if (st[next_x][next_y] || a[next_x][next_y] == '.') continue;
                st[next_x][next_y] = 1;
                q.push({next_x, next_y});
            }
        }
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 0; i < n; ++i) cin >> a[i];
        
        int res = 0;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (!st[i][j] && a[i][j] == 'W') {
                    res ++;
                    bfs(i, j);
                }
            }
        }
        cout << res;
        return 0;
    }
    

    acwing1106山峰和山谷
    N*M的地,每个点上有一个数字,表示高度,如果当前点和周围8个方向的点高度相同,那么可以相连起来成为连通块。如果当前连通块比周围连通块都高,那么该连通块为山峰;如果当前连通块比周围连通块都低,那么该连通块为山谷。求山峰和山谷的数目。
    N~1e3,每个点的权值~1e9

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int const N = 1e3 + 10;
    int n, fe, gu;
    int a[N][N];
    int st[N][N];
    queue<pair<int, int> > q;
    int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
    int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
    
    void bfs(int x, int y, int val) {
        q.push({x, y});
        st[x][y] = 1;
        while (q.size()) {
            auto t = q.front();
            q.pop();
            
            for (int i = 0; i < 8; ++i) {
                int next_x = t.first + dx[i], next_y = t.second + dy[i];
                if (next_x < 0 || next_x > n - 1 || next_y < 0 || next_y > n - 1) continue;
                if (val > a[next_x][next_y]) fe = 1;
                if (val < a[next_x][next_y]) gu = 1;
                if (st[next_x][next_y] || a[next_x][next_y] != val) continue;
                st[next_x][next_y] = 1;
                q.push({next_x, next_y});
            }
        }
    }
    
    int main() {
        cin >> n;
        bool flg = true;  // 判个特例,全部点的值都相同
        int v;
        for (int i = 0; i < n; ++i) 
            for (int j = 0; j < n; ++j) {
                cin >> a[i][j];
                if (!i && !j) v = a[i][j];
                if (a[i][j] != v) flg = false;
            }
        
        if (flg) {
            cout << 1 << " " << 1 << endl;
            return 0;
        }
        
        fe = 0, gu = 0;  // 判断是否出现山峰和山谷
        int cnt_fe = 0, cnt_gu = 0;  // 山峰数目和山谷数目
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (!st[i][j]) {
                    fe = 0, gu = 0;
                    bfs(i, j, a[i][j]);
                    if (fe && !gu) cnt_fe++;  // 只有比他高的,那么山峰数加一
                    if (!fe && gu) cnt_gu++;  // 只有比他低的,那么山谷数加一
                }
            }
        }
        cout << cnt_fe << " " << cnt_gu;
        return 0;
    }
    
  • 相关阅读:
    让c像python一样可以在命令行写代码并且编译
    动态链接库找不到 : error while loading shared libraries: libgsl.so.0: cannot open shared object file: No such file or directory
    为什么shell中变量赋值不能有空格
    在hyper安装openwrt
    linux扩展lvm磁盘
    docker的基本使用
    tmux与vim主题不一致
    linux centos cli all proxy
    couchDB入门
    tmux复制到windows剪贴板/粘贴板的坑
  • 原文地址:https://www.cnblogs.com/spciay/p/13383129.html
Copyright © 2020-2023  润新知