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

}
相关推荐
小李子呢021111 小时前
前端八股6---v-model双向绑定
前端·javascript·算法
2301_8227032012 小时前
Flutter 框架跨平台鸿蒙开发 - 创意声音合成器应用
算法·flutter·华为·harmonyos·鸿蒙
cmpxr_12 小时前
【C】数组名、函数名的特殊
c语言·算法
KAU的云实验台12 小时前
【算法精解】AIR期刊算法IAGWO:引入速度概念与逆多元二次权重,可应对高维/工程问题(附Matlab源码)
开发语言·算法·matlab
会编程的土豆12 小时前
【数据结构与算法】再次全面了解LCS底层
开发语言·数据结构·c++·算法
大熊背13 小时前
如何利用Lv值实现三级降帧
算法·自动曝光·lv·isppipeline
大尚来也14 小时前
驾驭并发:.NET多线程编程的挑战与破局之道
java·前端·算法
向阳而生,一路生花14 小时前
深入浅出 JDK7 HashMap 源码分析
算法·哈希算法
君义_noip14 小时前
信息学奥赛一本通 4150:【GESP2509七级】⾦币收集 | 洛谷 P14078 [GESP202509 七级] 金币收集
c++·算法·gesp·信息学奥赛·csp-s
摸个小yu14 小时前
【力扣LeetCode热题h100】链表、二叉树
算法·leetcode·链表