搜索——flood fill

        flood fill,即洪水泛滥,用来解决连通块问题,通过宽搜(bfs)找到某个点所在的连通块,用深搜(dfs)的话,在数据范围较大的时候可能存在爆桟的情况。

1097. 池塘计数 - AcWing题库

农夫约翰有一片 N∗M 的矩形土地。

最近,由于降雨的原因,部分土地被水淹没了。

现在用一个字符矩阵来表示他的土地。

每个单元格内,如果包含雨水,则用”W”表示,如果不含雨水,则用”.”表示。

现在,约翰想知道他的土地中形成了多少片池塘。

每组相连的积水单元格集合可以看作是一片池塘。

每个单元格视为与其上、下、左、右、左上、右上、左下、右下八个邻近单元格相连。

请你输出共有多少片池塘,即矩阵中共有多少片相连的”W”块。

输入格式

第一行包含两个整数 N 和 M。

接下来 N 行,每行包含 M 个字符,字符为”W”或”.”,用以表示矩形土地的积水状况,字符之间没有空格。

输出格式

输出一个整数,表示池塘数目。

数据范围

1≤N,M≤1000

输入样例:
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
输出样例:
3

思路:题目要求我们算出雨水的连通块,我们枚举每一个点,当遍历到雨水点进行宽搜,将其连通块全部赋值为非雨水点,避免重复遍历,累加遍历的连通块即可得到答案。

#include 
#include 
#include 
#include 

using namespace std;

typedef pair PII;

const int N = 1010;

int n, m;
char g[N][N];

void bfs(int x, int y)
{
    queue q;
    q.push({x, y});
    
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        
        //小技巧,遍历周围八个点
        for(int xx = t.first - 1; xx <= t.first + 1; xx ++  )
            for(int yy = t.second - 1; yy <= t.second + 1; yy ++ )
                if(xx >= 0 && xx < n && yy >= 0 && yy < m && g[xx][yy] == 'W')
                {
                    g[xx][yy] = '.';
                    q.push({xx, yy});
                }
    }
}

int main()
{
    cin >> n >> m;
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j < m; j ++ )
            cin >> g[i][j];
            
    int res = 0;
    
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j < m; j ++ )
            if(g[i][j] == 'W')
            {
                res ++ ;
                bfs(i, j);
            }
    
    cout << res;
            
    return 0;
}

1098. 城堡问题 - AcWing题库

1106. 山峰和山谷 - AcWing题库

你可能感兴趣的:(acwing算法提高课学习记录,数据结构,算法,c++)