岛屿个数蓝桥B组

本文描述了一道关于在二维矩阵中使用广度优先搜索(BFS)算法解决岛屿计数问题的编程题目,参赛者需遍历矩阵并标记陆地,避免重复计算,特殊情况下考虑最外层无水的情况。
摘要由CSDN通过智能技术生成

岛屿个数

给我点个赞吧!!!!link

来源:第十四届蓝桥杯省赛C++ B组

标签:BFS, DFS

思路:遍历最外层的海水,给外层海水打上标记,在遍历海水时,遇到的陆地即是我们要岛屿,为了防止重复计算答案,给当前的岛屿也打上标记,并且答案ans+1。这样还没结束,有个特例是我们上面没考虑到的,就是最外层没水,那么答案就是1个岛屿,因为这个岛屿把海水全围住了。

#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#define PII pair<int, int>
#define x first
#define y second
using namespace std;

const int N = 55;

int T;
int n, m;
int ans = 0;
char g[N][N];
bool st[N][N];
int dx[8] = {-1, 1, 0, 0, -1, -1, 1, 1};
int dy[8] = {0, 0, -1, 1, -1, 1, -1, 1};

void bfs(int i, int j, char c)
{
    queue<PII> q;
    q.push({i, j});
    st[i][j] = true;
    while(q.size())
    {
        auto t = q.front();
        q.pop();
        
        // 海水是无孔不入的,所以只要八个方向有一个没围住,就说明当前岛屿没围住海水
        for(int i = 0; i < (c == '0'?8:4); i ++ )
        {
            int x = t.x + dx[i], y = t.y + dy[i];
            if(x < 1 || x > n || y < 1 || y > m) continue;
            if(c == '0' && g[x][y] == '1' && !st[x][y]){
                ans ++;
                bfs(x, y, '1'); // 给岛屿打标记,防止重复计算
            }
            if(g[x][y] != c || st[x][y]) continue;
            st[x][y] = true;
            q.push({x, y});
        }
    }
}

int main()
{
    cin >> T;
    while(T -- )
    {
        memset(st, 0, sizeof st);
        cin >> n >> m;
        for(int i = 1; i <= n; i ++ )
            scanf("%s", g[i] + 1);
        ans = 0;
        bool f = false;
        for(int i = 1; i <= n; i ++ )
        {
            if(g[i][1] == '0' && !st[i][1]) bfs(i, 1, '0'), f = true;
            if(g[i][m] == '0' && !st[i][m]) bfs(i, m, '0'), f = true;
        }
        for(int i = 1; i <= m; i ++ )
        {
            if(g[1][i] == '0' && !st[1][i]) bfs(1, i, '0'), f = true;
            if(g[n][i] == '0' && !st[n][i]) bfs(n, i, '0'), f = true;
        }
        if(!f) ans = 1;
        cout << ans << endl;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值