【代码随想录训练营第42期 Day52打卡 - 岛屿问题2

news2024/9/21 10:56:26

目录

一、做题心得

二、题目与题解

题目一:卡码网 101. 孤岛的总面积

题目链接

题解:DFS

题目二:卡码网 102. 沉没孤岛

题目链接

题解:DFS

三、小结


一、做题心得

今天做题时间比较晚了,只打卡完成了岛屿问题后续的两道题,剩下两道后边补。

对我个人而言,更习惯用 DFS 解决这一类搜索问题,今天也是用的DFS实现,两道题整体思路和昨天的岛屿问题一致,多的就是需要处理孤岛与边缘陆地的问题。

二、题目与题解

题目一:卡码网 101. 孤岛的总面积

题目链接

101. 孤岛的总面积 (kamacoder.com)

题目描述

给定一个由 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

输出示例

1

提示信息

在矩阵中心部分的岛屿,因为没有任何一个单元格接触到矩阵边缘,所以该岛屿属于孤岛,总面积为 1。

数据范围:

1 <= M, N <= 50。

题解:DFS

对于处理孤岛总面积的关键:

要求找到孤岛即不靠边的陆地面积,那么我们只要从周边找到陆地然后通过dfs将周边靠陆地且相邻的陆地都变成水 -- 将边缘陆地(边缘岛屿)变成水,然后再去重新遍历地图统计此时还剩下的陆地就可以了

分别处理四个边缘,我们从边缘向中间靠近,对于同一片边缘岛屿的陆地,都变成水,剩下的陆地就是孤岛,求出其面积即可。即:

    // 左右边缘
    for (int i = 0; i < n; i++) {
        if (grid[i][0] == 1) {
            dfs(i, 0);  // 如果左边缘有陆地,则清除
        }
        if (grid[i][m - 1] == 1) {
            dfs(i, m - 1);  // 如果右边缘有陆地,则清除
        }
    }
    // 上下边缘
    for (int j = 0; j < m; j++) {
        if (grid[0][j] == 1) {
            dfs(0, j);  // 如果上边缘有陆地,则清除
        }
        if (grid[n - 1][j] == 1) {
            dfs(n - 1, j);  // 如果下边缘有陆地,则清除
        }
    }

其中,陆地变为水: grid[curx][cury] = 0;

完整代码如下(主体代码就和昨天打卡一致,这里就不细说了):

#include <bits/stdc++.h>
using namespace std;

const int N = 55; 
int n, m; 
int grid[N][N]; 
bool visited[N][N] = {0}; 
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 
int ans = 0; 

void dfs(int curx, int cury) {
    grid[curx][cury] = 0;   // 将当前边缘陆地变成水
    ans++;      // 计算当前岛屿的大小
    for (int i = 0; i < 4; i++) { 
        int nextx = curx + dx[i], nexty = cury + dy[i]; 
        if (nextx < 0 || nextx >= n || nexty < 0 || nexty >= m) {
            continue; 
        }
        if (visited[nextx][nexty] || grid[nextx][nexty] == 0) {
            continue; 
        }
        visited[nextx][nexty] = true; 
        dfs(nextx, nexty); 
    }
}

int main() {
    std::ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0); 
    cin >> n >> m; 
    for (int i = 0; i < n; i++) { 
        for (int j = 0; j < m; j++) { 
            cin >> grid[i][j]; 
        }
    }
    /* 遍历网格的边缘,并使用dfs清除所有靠边的陆地 */
    // 左右边缘
    for (int i = 0; i < n; i++) {
        if (grid[i][0] == 1) {
            dfs(i, 0);  // 如果左边缘有陆地,则变为是水
        }
        if (grid[i][m - 1] == 1) {
            dfs(i, m - 1);  // 如果右边缘有陆地,则变为水
        }
    }
    // 上下边缘
    for (int j = 0; j < m; j++) {
        if (grid[0][j] == 1) {
            dfs(0, j);  // 如果上边缘有陆地,则变为水
        }
        if (grid[n - 1][j] == 1) {
            dfs(n - 1, j);  // 如果下边缘有陆地,则变为水
        }
    }
    // 重置结果,开始计算不靠边的陆地面积
    ans = 0;
    for (int i = 0; i < n; i++) {   // 再次遍历网格
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 1) {      // 如果是陆地且不靠边
                dfs(i, j);      // 使用dfs计算陆地的大小
            }
        }
    }
    cout << ans << endl;    // 输出边缘陆地即不靠边的陆地总面积
    return 0;
}

题目二:卡码网 102. 沉没孤岛

题目链接

102. 沉没孤岛 (kamacoder.com)

题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,岛屿指的是由水平或垂直方向上相邻的陆地单元格组成的区域,且完全被水域单元格包围。孤岛是那些位于矩阵内部、所有单元格都不接触边缘的岛屿。

现在你需要将所有孤岛“沉没”,即将孤岛中的所有陆地单元格(1)转变为水域单元格(0)。

输入描述

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

之后 N 行,每行包含 M 个数字,数字为 1 或者 0,表示岛屿的单元格。

输出描述

输出将孤岛“沉没”之后的岛屿矩阵。 注意:每个元素后面都有一个空格

输入示例

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

输出示例

1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 1 1

提示信息

将孤岛沉没。

数据范围:

1 <= M, N <= 50。

题解:DFS

这题和上题思路基本一致,这里有个很巧妙的解法:将边缘岛屿的陆地全标记为 2,孤岛不做标记(仍为1),最后将原本的 1 (孤岛)变为 0,边缘陆地的 2 变为 1 ,就实现了孤岛的沉没。

代码如下:

#include <bits/stdc++.h>
using namespace std;

const int N = 55; 
int n, m; 
int grid[N][N]; 
bool visited[N][N] = {0}; 
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 

void dfs(int curx, int cury) {
    grid[curx][cury] = 2;   // 注意:将边缘孤岛(边缘陆地)标记为 2
    for (int i = 0; i < 4; i++) { 
        int nextx = curx + dx[i], nexty = cury + dy[i]; 
        if (nextx < 0 || nextx >= n || nexty < 0 || nexty >= m) {
            continue; 
        }
        if (visited[nextx][nexty] || grid[nextx][nexty] == 0) {
            continue; 
        }
        visited[nextx][nexty] = true; 
        dfs(nextx, nexty); 
    }
}

int main() {
    std::ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0); 
    cin >> n >> m; 
    for (int i = 0; i < n; i++) { 
        for (int j = 0; j < m; j++) { 
            cin >> grid[i][j]; 
        }
    }
    /* 遍历网格的边缘,并使用dfs清除所有靠边的陆地 */
    // 左右边缘
    for (int i = 0; i < n; i++) {
        if (grid[i][0] == 1) {
            dfs(i, 0);  // 如果左边缘有陆地,则记为2
        }
        if (grid[i][m - 1] == 1) {
            dfs(i, m - 1);  // 如果右边缘有陆地,记为2
        }
    }
    // 上下边缘
    for (int j = 0; j < m; j++) {
        if (grid[0][j] == 1) {
            dfs(0, j);  // 如果上边缘有陆地,则记为2
        }
        if (grid[n - 1][j] == 1) {
            dfs(n - 1, j);  // 如果下边缘有陆地,则记为2
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 1) {          //沉没孤岛 -- 孤岛从 1 变为 0
                grid[i][j] = 0;
            }
            if (grid[i][j] == 2) {      // 边缘岛屿的陆地保留 -- 2 回到 1
                grid[i][j] = 1;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m - 1; j++) {
            cout << grid[i][j] << " ";
        }
        cout << grid[i][m - 1] << endl;
    }
    return 0;
}

三、小结

图论这一块内容相对来说难度较大,但其实理清思路了慢慢去写也能够收获很多。今天的打卡先到此结束,后边会继续加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2111672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

条件生成模型 (conditional generation)

我们之前讲的 GAN 中的生 成器&#xff0c;它没有输入任何的条件&#xff0c;它只是输入一个随机的分布&#xff0c;然后产生出来一张图片。我们现 在想要更进一步的是希望可以操控生成器的输出&#xff0c;我们给它一个条件x&#xff0c;让他根据条件x跟 输入z 来产生输出y。那…

硬件-经典开机电路

文章目录 一&#xff1a;网友公司祖传的开机电路二&#xff1a;电路符号名称三&#xff1a;电路原理分析道友&#xff1a;对于利益相关的人&#xff0c;要展示你的实力和智力。对于利益不相关的人&#xff0c;展示你的礼貌就好。 一&#xff1a;网友公司祖传的开机电路 业务逻辑…

【二】TDEngine快速入门

TDEngine快速入门 目录 TDEngine深入理解 概述 一、核心概念解析 二、基本操作 三、可视化管理工具 总结 概述 TDEngine创始人在官方出品的书籍中写到&#xff1a;我观察到&#xff0c;无论是出行行业还是更广义的运输行业&#xff0c;以及分布式能源系统&#xff0c;都将…

【网络安全 | 渗透工具】Cencys+Shodan使用教程

原创文章,不得转载。 文章目录 Cencys准备语法全文搜索字段和值搜索通配符搜索布尔逻辑搜索嵌套搜索时间相关搜索范围搜索双引号 (")转义序列和保留字符Censys 搜索语言中的主机查询查看主机搜索结果Censys 搜索语言中的证书查询查看证书搜索结果生成报告其余Shodan准备使…

解决MongoDB创建用户报错command createUser requires authentication

1、执行创建用户报错如下&#xff1a; 2、解决方法 2.1 关闭 MongoDB /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongod.conf --shutdown 2.2 修改配置文件 vim /usr/local/mongodb/mongod.conf 将security.authorization值从enabled改为disabled 2.3 启动MongoD…

HTML/CSS/JS学习笔记 Day2(HTML--标签 上)

跟着该视频学习&#xff0c;记录笔记&#xff1a;【黑马程序员pink老师前端入门教程&#xff0c;零基础必看的h5(html5)css3移动端前端视频教程】https://www.bilibili.com/video/BV14J4114768?p12&vd_source04ee94ad3f2168d7d5252c857a2bf358 Day2 内容梳理&#xff1a;…

redission中的锁分类

redis 分布式锁的核心命令 redis分布式锁的实现主要是依靠setnx和expire两个命令完成。 注意&#xff1a;由于setnx和expire是两个命令&#xff0c;会存在如果 setnx 是成功的&#xff0c;但是 expire 设置失败&#xff0c;一旦出现了释放锁失败&#xff0c;或 者没有手工释放…

用华为智驾,开启MPV的下半场

作者 |老缅 编辑 |德新 8月28日&#xff0c;岚图正式对外公布了全球首款搭载华为乾崑智驾和鸿蒙座舱的MPV——全新岚图梦想家。 新车定位「全景豪华科技旗舰MPV」&#xff0c;全系标配四驱&#xff0c;分为四驱鲲鹏版和四驱乾崑版。 其中岚图逍遥座舱和鲲鹏智驾构成的鲲鹏版…

yolov5 +gui界面+单目测距 实现对图片视频摄像头的测距

可实现对图片&#xff0c;视频&#xff0c;摄像头的检测 项目概述 本项目旨在实现一个集成了YOLOv5目标检测算法、图形用户界面&#xff08;GUI&#xff09;以及单目测距功能的系统。该系统能够对图片、视频或实时摄像头输入进行目标检测&#xff0c;并估算目标的距离。通过…

【Java】基于JWT+Token实现完整登入功能(实操)

Java系列文章目录 补充内容 Windows通过SSH连接Linux 第一章 Linux基本命令的学习与Linux历史 文章目录 Java系列文章目录一、前言二、学习内容&#xff1a;三、问题描述四、解决方案&#xff1a;4.1 认识依赖4.2 使用JWT4.3 登入实现4.4 配置拦截器4.5 获取数据 五、总结&…

Unity数据持久化 之 使用Excel.DLL读写Excel表格

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​​ 终于找到一个比较方便容易读表的方式了&#xff0c;以前用json读写excel转的cvs格式文件我怎么使用怎么别扭&#xf…

合宙4G模组Air780EX——产品规格书

Air780EX 是合宙通信推出的LTE Cat.1 bis通信模块&#xff1b; Air780EX采用移芯EC618平台&#xff0c;支持LTE 3GPP Rel.13 技术&#xff1b; Air780EX 是4G全网通模块&#xff0c;可适应不同的运营商和产品&#xff0c;确保产品设计的最大灵活性。 其主要特点和优势可以总…

(一)十分简易快速 自己训练样本 opencv级联haar分类器 车牌识别

🍂1、不说废话,现象展示 🍃图片识别 🍃视频识别 自己训练样本 十分简易快速 opencv级联ha

个股场外期权怎么交易?场外期权交易流程是怎样的?

今天带你了解个股场外期权怎么交易&#xff1f;场外期权交易流程是怎样的&#xff1f;个股场外期权是一种非标准化的期权合约&#xff0c;通常在场外市场&#xff08;OTC市场&#xff09;由金融机构和投资者之间进行交易。 场外个股期权主要功能 风险管理&#xff1a; 帮助投…

太速科技-基于Kintex-7 XC7K325T的FMC USB3.0四路光纤数据转发卡

基于Kintex-7 XC7K325T的FMC USB3.0四路光纤数据转发卡 一、板卡概述   本板卡基于Xilinx公司的FPGAXC7K325T-2FFG900 芯片&#xff0c;pin_to_pin兼容FPGAXC7K410T-2FFG900 &#xff0c;支持64bit DDR3容量2GByte&#xff0c;USB3.0接口&#xff0c;HPC的FMC连接器&#xff…

安卓玩机工具-----通用安卓玩机工具 “搞机助手”界面预览 推荐

在网络中有很多很好玩的工具。方便安卓机型联机使用各种功能。系列博文将详细的演示有些工具的特点与使用方法 搞机助手 作者&#xff1a;流水断崖 目前开发功能有&#xff1a;Twrp recovery全自动刷机&#xff0c;免Root冻结、卸载预装软件&#xff0c;免Root激活&#xff…

1-9 图像膨胀 opencv树莓派4B 入门系列笔记

目录 一、提前准备 二、代码详解 kernel np.ones((3, 3), np.uint8) _, binary_image cv2.threshold(image, 127, 255, cv2.THRESH_BINARY) dilated_image cv2.dilate(binary_image, kernel, iterations1) 三、运行现象 四、完整代码 五、完整工程贴出 一、提前准备 …

【vue css】background设置背景图片不显示问题

问题&#xff1a; 如上图所示&#xff0c;添加背景图片页面没有显示 解决&#xff1a; 添加background-position: center center 即可显示 但是不知道为什么添加这个属性就可以&#xff0c;求大神解惑

端口安全老化细节

我们都知道port-security aging-time命令用来配置端口安全动态MAC地址的老化时间&#xff0c;但是后面还可以加上类型&#xff1a; [SW1-GigabitEthernet0/0/1]port-security aging-time 5 type absolute Absolute time 绝对老化 inactivity Inactivity time相对老化 …

网络协议-SSH

SSH&#xff08;Secure Shell&#xff09;协议是一种广泛使用的网络协议&#xff0c;用于安全地进行远程登录和数据传输。SSH协议通过加密技术保证了数据的安全性&#xff0c;防止数据在传输过程中被窃听、篡改或伪造。SSH协议的通信认证过程主要包括以下几个步骤&#xff1a; …