【算法打卡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;

}
相关推荐
灵感__idea6 小时前
Hello 算法:众里寻她千“百度”
前端·javascript·算法
Wect16 小时前
LeetCode 130. 被围绕的区域:两种解法详解(BFS/DFS)
前端·算法·typescript
NAGNIP1 天前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
颜酱1 天前
单调栈:从模板到实战
javascript·后端·算法
CoovallyAIHub2 天前
仿生学突破:SILD模型如何让无人机在电力线迷宫中发现“隐形威胁”
深度学习·算法·计算机视觉
CoovallyAIHub2 天前
从春晚机器人到零样本革命:YOLO26-Pose姿态估计实战指南
深度学习·算法·计算机视觉
CoovallyAIHub2 天前
Le-DETR:省80%预训练数据,这个实时检测Transformer刷新SOTA|Georgia Tech & 北交大
深度学习·算法·计算机视觉
CoovallyAIHub2 天前
强化学习凭什么比监督学习更聪明?RL的“聪明”并非来自算法,而是因为它学会了“挑食”
深度学习·算法·计算机视觉
CoovallyAIHub2 天前
YOLO-IOD深度解析:打破实时增量目标检测的三重知识冲突
深度学习·算法·计算机视觉
NAGNIP2 天前
轻松搞懂全连接神经网络结构!
人工智能·算法·面试