AcWing算法提高课-2.1.1池塘计数

宣传一下算法提高课整理 <—

CSDN个人主页:更好的阅读体验 <—

csdn

题目传送门点这里

题目描述

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

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

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

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

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

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

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

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

输入格式

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

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

输出格式

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

数据范围

1 ≤ N , M ≤ 1000 1≤N,M≤1000 1N,M1000

样例输入

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

思路

Flood Fill算法,好高大上的名字!
但它其实就是BFS

用途: 求一个图形中连通块的个数

步骤:

  1. 找到任意一个连通块包含的点,这步可以直接遍历找
  2. 在这个连通块上跑BFS,把这个连通块的所有点都打上标记(当然,把W改成.也是可以的)
  3. 继续找连通块,重复步骤1和2,直到所有连通块都被遍历过
  4. 找到一个连通块就给答案加一,输出答案即可

注意:

  • 图里面的字符大小写和全半角不要搞混
  • 输入的时候不要按字符输入,不然会输进去\nspace这些奇奇怪怪的东西,导致WA
  • 可以放心用STL的queue,不会超时

算法时间复杂度

BFS差不多会把所有点跑一遍,因此时间复杂度差不多是 O ( n m ) O(nm) O(nm)


AC Code

C + + C++ C++

#include <iostream>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

const int N = 1010;
int dx[] = {1, 1, 1, 0, -1, -1, -1, 0};
int dy[] = {-1, 0, 1, 1, 1, 0, -1, -1};

int n, m;
char a[N][N];
int res;

void bfs(int x, int y)
{
    queue<PII> q;
    q.push({x, y});
    while (q.size())
    {
        auto t = q.front();
        q.pop();
        int px = t.first, py = t.second;
        for (int i = 0; i < 8; i ++ )
        {
            int xx = px + dx[i], yy = py + dy[i];
            if (xx >= 0 && xx < n && yy >= 0 && yy < m && a[xx][yy] == 'W')
            {
                a[xx][yy] = '.';
                q.push({xx, yy});
            }
        }
    }
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++ )
        scanf("%s", &a[i]);

    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (a[i][j] == 'W')
            {
                bfs(i, j);
                res ++ ;
            }

    printf("%d\n", res);

    return 0;
}

a

最后,如果觉得对您有帮助的话,点个赞再走吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星河依旧长明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值