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

}
相关推荐
CN-Dust9 小时前
【C++】while语句例题专题
数据结构·c++·算法
灵智实验室10 小时前
PX4位置速度估计技术详解(四):LPE 激光雷达高度融合的实现错误
算法·无人机·px 4
CQU_JIAKE10 小时前
【A】3742,3387,并查集
算法
gihigo199810 小时前
CHAN时延估计算法(二维/三维定位实现)
算法
freexyn10 小时前
Matlab自学笔记七十六:表达式的展开、因式分解、化简、合并同类项
笔记·算法·matlab
样例过了就是过了10 小时前
LeetCode热题 不同路径
c++·算法·leetcode·动态规划
dog25011 小时前
圆锥曲线和二次曲线
开发语言·网络·人工智能·算法·php
Wadli11 小时前
27.单调队列
算法
Navigator_Z11 小时前
LeetCode //C - 1031. Maximum Sum of Two Non-Overlapping Subarrays
c语言·算法·leetcode
Wect11 小时前
LeetCode 97. 交错字符串:动态规划详解
前端·算法·typescript