【算法打卡day3 | 2026-02-08 周日 | 算法: BFS】3_卡码网99_计数孤岛_BFS | 4_卡码网100_最大岛屿的面积DFS

- 第 163 篇 -
Date: 2026 - 02- 08 (周日)
Author: 郑龙浩(仟墨)

2026-02-08 周日 | 算法打卡day3

文章目录

3_卡码网99_计数孤岛_DFS

使用BFS

题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。

后续 N 行,每行包含 M 个数字,数字为 1 或者 0。

输出描述

输出一个整数,表示岛屿的数量。如果不存在岛屿,则输出 0。

输入示例

复制代码
4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

输出示例

复制代码
3
cpp 复制代码
// Date: 2026-02-08 Author:郑龙浩

// 3_卡码99_计数孤岛_BFS.cpp

// BFS

// 用时:

#include "bits/stdc++.h"

using namespace std;

  

int direction[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

  

// 技巧:只要加入队列,就立刻标记(代表走过) + 先给(x, y)当前位置标记,再给周围的位置标记

  

// 队列在广度优先搜索中发挥着核心作用。由于队列遵循先进先出的原则,它能确保算法按照层级顺序遍历图中的节点。具体来说,

// 算法会从起始节点开始,将其加入队列并标记为已访问。在遍历过程中,每当从队列前端取出一个节点进行处理时,

// 会立即将该节点的所有未访问且符合条件的相邻节点加入队列末尾。这种机制保证了先被发现的节点会先被处理,

// 从而使搜索范围从起点开始逐层均匀向外扩展,首先处理距离为1的直接邻居,接着处理距离为2的节点,

// 依此类推,最终实现了按层级遍历的效果,这正是广度优先搜索"广度"二字的体现。

  

void bfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {

    int heigth = grid.size();

    int width = grid[0].size();

  

    queue <pair <int, int>> que;

    que.push({x, y}); // 先将当前坐标放入que中去

    visited[x][y] = true; // 标记当前

    int curX, curY, nextX, nextY;

    while (!que.empty()) {

  

        // 取出队列中的岛屿坐标

        curX = que.front().first;

        curY = que.front().second;

        que.pop(); // 取出岛屿后弹出

  

        for (int i = 0; i < 4; i++) {

            nextX = curX + direction[i][0];

            nextY = curY + direction[i][1];

            if (nextX >=0 && nextX < heigth && nextY >= 0 && nextY < width && grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) {

                que.push({nextX, nextY}); // 将下一个坐标加入que

                visited[nextX][nextY] = true;

            }

        }

    }    

}

  

int main(void) {

    ios::sync_with_stdio(0);

    cin.tie(0); cout.tie(0);

    int N, M, cnt= 0;

    cin >> N >> M;

  

    vector <vector <int>> grid(N, vector <int>(M, 0));

    vector <vector <bool>> visited(N, vector <bool>(M, false));

    for (int i = 0; i < N; i++) {

        for (int j = 0; j < M; j++) {

            cin >> grid[i][j];

        }

    }

  

    for (int i = 0; i < N; i++) {

        for (int j = 0; j < M; j++) {

            if (grid[i][j] == 1 && visited[i][j] == 0) { // 如果(i, j)位置是陆地且没有访问过,则找到了新的岛屿,cnt++ 且 使用BFS广搜附近所有与(i, j)连接的岛屿,如果找到了,就用visited标记下

                cnt++;

                bfs(grid, visited, i, j);

            }

        }

    }

    cout << cnt;

    return 0;

}

4_卡码网100_最大岛屿的面积

**题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,计算岛屿的最大面积。岛屿面积的计算方式为组成岛屿的陆地的总数。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。后续 N 行,每行包含 M 个数字,数字为 1 或者 0,表示岛屿的单元格。

输出描述

输出一个整数,表示岛屿的最大面积。如果不存在岛屿,则输出 0。

输入示例

复制代码
4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

输出示例

复制代码
4
cpp 复制代码
// Date: 2026-02-08 Author:郑龙浩

// 4_卡码网100_最大岛屿的面积

// 方法1:DFS

// 用时:

#include "bits/stdc++.h"

using namespace std;

  

int direction[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

  

int S = 0; // 每个小岛面积

  

void dfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {

    int width = grid[0].size();

    int height = grid.size();

  

    visited[x][y] = true;

    S++;

  

    for (int i = 0; i < 4; i++) {

        int nextX = x + direction[i][0];

        int nextY = y + direction[i][1];

  

        if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width && grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) {

            dfs(grid, visited, nextX, nextY);

        }

    }

  

    return; // 可写可不写

}

  

int main(void) {

    ios::sync_with_stdio(0);

    cin.tie(0); cout.tie(0);

  

    int N, M, max = 0;

    cin >> N >> M;

  

    vector <vector <int>> grid(N, vector <int>(M, 0));

    vector <vector <bool>> visited(N, vector <bool>(M, false));

  

    for (int i = 0; i < N; i++) {

        for (int j = 0; j < M; j++) {

            cin >> grid[i][j];

        }

    }

  

    for (int i = 0; i < N; i++) {

        for (int j = 0; j < M; j ++) {

            if (grid[i][j] == 1 && visited[i][j] == false) {

                S = 0; // 每次发现新的岛屿,都要将面积重置为0

                dfs(grid, visited, i, j);

                if (max < S) max = S;

            }

        }

    }

  

    cout << max;

    return 0;

}
相关推荐
Ll13045252986 小时前
Leetcode二叉树part4
算法·leetcode·职场和发展
颜酱7 小时前
二叉树遍历思维实战
javascript·后端·算法
宝贝儿好7 小时前
第二章: 图像处理基本操作
算法
小陈phd7 小时前
多模态大模型学习笔记(二)——机器学习十大经典算法:一张表看懂分类 / 回归 / 聚类 / 降维
学习·算法·机器学习
@––––––7 小时前
力扣hot100—系列4-贪心算法
算法·leetcode·贪心算法
CoovallyAIHub7 小时前
让本地知识引导AI追踪社区变迁,让AI真正理解社会现象
深度学习·算法·计算机视觉
CoderCodingNo7 小时前
【GESP】C++ 二级真题解析,[2025年12月]第一题环保能量球
开发语言·c++·算法
yumgpkpm7 小时前
预测:2026年大数据软件+AI大模型的发展趋势
大数据·人工智能·算法·zookeeper·kafka·开源·cloudera
CoovallyAIHub7 小时前
AAAI 2026这篇杰出论文说了什么?用LLM给CLIP换了个“聪明大脑”
深度学习·算法·计算机视觉