笔记:代码随想录算法训练营day58:101.孤岛的总面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿

news2025/3/22 23:43:14

学习资料:代码随想录

文中含大模型生成内容

101. 孤岛的总面积

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

所以找周边都是水的陆地的方法就是找边缘的陆地然后删除它连同它的连通的陆地

深搜
 

#include <iostream>
#include <vector>
using namespace std;
 
int dir[4][2]={0,1,-1,0,0,-1,1,0};
 
void dfs(vector<vector<int>>& fiji,int x,int y){
    fiji[x][y]=0;
    for(int i=0;i<4;i++){
        int xnext=x+dir[i][0];
        int ynext=y+dir[i][1];
        if(xnext<0||xnext>=fiji.size()||ynext<0||ynext>=fiji[0].size()) continue;
        if(fiji[xnext][ynext]==0)continue;
        else{dfs(fiji,xnext,ynext);}
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> fiji(n,vector<int>(m,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>fiji[i][j];
        }
 
    }
     
    for(int i=0;i<n;i++){
        if(fiji[i][0]==1){
            dfs(fiji,i,0);
        }
        if(fiji[i][m-1]==1){
            dfs(fiji,i,m-1);
        }
    }
    for(int j=0;j<m;j++){
        if(fiji[0][j]==1){
            dfs(fiji,0,j);
        }
        if(fiji[n-1][j]==1){
            dfs(fiji,n-1,j);
        }
    }
    int count =0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(fiji[i][j]==1) count++;
        }
    }
    cout<<count<<endl;
}

广搜
 

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
 
int dir[4][2]={0,1,-1,0,0,-1,1,0};
 
void bfs(vector<vector<int>>& fiji,int x,int y){
    fiji[x][y]=0;
    queue<pair<int,int>> que;
    que.push({x,y});
 
    while(!que.empty()){
        pair<int,int> cur=que.front();
        que.pop();
        for(int i=0;i<4;i++){
            int xnext = cur.first+dir[i][0];
            int ynext = cur.second+dir[i][1];
            if(xnext<0||xnext>=fiji.size()||ynext<0||ynext>=fiji[0].size()) continue;
            if(fiji[xnext][ynext]==1){
                que.push({xnext,ynext});
                fiji[xnext][ynext]=0;
            }
        }
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> fiji(n,vector<int>(m,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>fiji[i][j];
        }
 
    }
     
    for(int i=0;i<n;i++){
        if(fiji[i][0]==1){
            bfs(fiji,i,0);
        }
        if(fiji[i][m-1]==1){
            bfs(fiji,i,m-1);
        }
    }
    for(int j=0;j<m;j++){
        if(fiji[0][j]==1){
            bfs(fiji,0,j);
        }
        if(fiji[n-1][j]==1){
            bfs(fiji,n-1,j);
        }
    }
    int count =0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(fiji[i][j]==1) count++;
        }
    }
    cout<<count<<endl;
}

深度优先搜索(DFS)或广度优先搜索(BFS) 中,我们通常用 visited 数组来标记已经访问过的点,以防止:

  • 重复访问,导致超时
  • 无限递归,导致栈溢出(Stack Overflow)

通常如果 不能修改原数组,我们就要 额外开一个 visited 数组 来记录访问情况。

这里的 grid 只有两种值:

  • 1(陆地)
  • 0(海洋)

我们遍历 grid 时:

  1. 遇到 1(陆地)

    • 说明它是未访问过的,然后我们调用 dfs(grid, x, y)
    • 在 DFS 里,我们把 grid[x][y] 直接改成 0,代表这个点已经被访问过了。
    • 这样,我们就不会 重复访问 这个点,也不会影响后续的 DFS 逻辑。
  2. 遇到 0(海洋)

    • 要么是原始的海洋
    • 要么是 DFS 过程中被修改成 0 的陆地
    • 不需要再访问,所以直接跳过
  3. 这样,我们实际上是用 grid 自己充当 visited 数组!

102. 沉没孤岛

卡码网题目链接(ACM模式)

先把边缘的陆地标记成2,然后把陆地1改成水0,最后把边缘的陆地改回1就可以了

深搜

#include <iostream>
#include <vector>
using namespace std;
 
int dir[4][2]={0,1,-1,0,0,-1,1,0};
void dfs(vector<vector<int>>& fiji,int x,int y){
    fiji[x][y]=2;
    for(int i=0;i<4;i++){
        int xnext = x+dir[i][0];
        int ynext = y+dir[i][1];
        if(xnext<0||xnext>=fiji.size()||ynext<0||ynext>=fiji[0].size()) continue;
        if(fiji[xnext][ynext]==1){
            dfs(fiji,xnext,ynext);
        }
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> fiji(n,vector<int>(m,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>fiji[i][j];
        }
    }
 
    for(int i=0;i<n;i++){
        if(fiji[i][0]==1) dfs(fiji,i,0);
        if(fiji[i][m-1]==1) dfs(fiji,i,m-1);
    }
    for(int j=0;j<m;j++){
        if(fiji[0][j]==1) dfs(fiji,0,j);
        if(fiji[n-1][j]==1) dfs(fiji,n-1,j);
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(fiji[i][j]==2){
                fiji[i][j]=1;
            }
            else if(fiji[i][j]==1){
                fiji[i][j]=0;
            }
            cout<<fiji[i][j]<<' ';
        }
        cout<<endl;
    }
 
 
 
}

 广搜

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
 
int dir[4][2]={0,1,-1,0,0,-1,1,0};
void dfs(vector<vector<int>>& fiji,int x,int y){
    queue<pair<int,int>> que;
    que.push({x,y});
    fiji[x][y]=2;
    while(!que.empty()){
        pair<int,int> cur=que.front();
        que.pop();
        for(int i=0;i<4;i++){
            int xnext = cur.first+dir[i][0];
            int ynext = cur.second+dir[i][1];
            if(xnext<0||xnext>=fiji.size()||ynext<0||ynext>=fiji[0].size()) continue;
            if(fiji[xnext][ynext]==1){
                que.push({xnext,ynext});
                fiji[xnext][ynext]=2;
            }
        }
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> fiji(n,vector<int>(m,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>fiji[i][j];
        }
    }
 
    for(int i=0;i<n;i++){
        if(fiji[i][0]==1) dfs(fiji,i,0);
        if(fiji[i][m-1]==1) dfs(fiji,i,m-1);
    }
    for(int j=0;j<m;j++){
        if(fiji[0][j]==1) dfs(fiji,0,j);
        if(fiji[n-1][j]==1) dfs(fiji,n-1,j);
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(fiji[i][j]==2){
                fiji[i][j]=1;
            }
            else if(fiji[i][j]==1){
                fiji[i][j]=0;
            }
            cout<<fiji[i][j]<<' ';
        }
        cout<<endl;
    }
 
 
 
}

103. 水流问题

卡码网题目链接(ACM模式)

从边缘向中间搜索高点并记录

#include <iostream>
#include <vector>
using namespace std;
int dir[4][2]={0,1,-1,0,0,-1,1,0};
 
void dfs(vector<vector<bool>>& visited,const vector<vector<int>>& fiji,int x,int y){
    if(visited[x][y]==true) return;
    visited[x][y] =true;
    for(int i=0;i<4;i++){
        int xnext = x+dir[i][0];
        int ynext = y+dir[i][1];
        if(xnext<0||xnext>=fiji.size()||ynext<0||ynext>=fiji[0].size()) continue;
        if(visited[xnext][ynext]==false&&fiji[x][y]<=fiji[xnext][ynext]){
            dfs(visited,fiji,xnext,ynext);
        }
    }
 
}
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> fiji(n,vector<int>(m,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>fiji[i][j];
        }
    }
 
    vector<vector<bool>> firstBorder(n,vector<bool>(m,0));
    vector<vector<bool>> secondBorder(n,vector<bool>(m,0)); 
    for(int i=0;i<n;i++){
        dfs(firstBorder,fiji,i,0);
        dfs(secondBorder,fiji,i,m-1);
    }   
    for(int j=0;j<m;j++){
        dfs(firstBorder,fiji,0,j);
        dfs(secondBorder,fiji,n-1,j);
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(firstBorder[i][j]&&secondBorder[i][j]){
                cout<<i<<' '<<j<<endl;
            }
        }
    }
}

一点小思考:第一种写法可否把visited改成全局变量然后时间复杂度也变成n*m?还是从两边往中间走合适,要不然使用全局visited并且还是用第一种方法遍历每一个点的话,遇到{{{2,2,2},{2,1,2}{2,2,2}},岂不是中间这个1也会被标记成true,这里是自己的思考,欢迎批评指正

104.建造最大岛屿

卡码网题目链接(ACM模式)

需要先遍历一遍给每块岛一个序号,记录数量,然后去搜索水域加上周围的岛,取最大值,

其中,岛的序号和面积用unordered_map记录

有一个有趣的一点是水周围的陆地可能是连在一起的,所以也要加上后就记录一下,用unordered_set记录

#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
using namespace std;
 
int dir[4][2]={0,1,-1,0,0,-1,1,0};
 
void dfs(vector<vector<int>>& fiji,vector<vector<bool>>& visited,int x,int y,int& mark,int& count){
    if(visited[x][y]==true) return;
    fiji[x][y]=mark;
    visited[x][y]=true;
    count++;
 
    for(int i=0;i<4;i++){
        int xnext = x+dir[i][0];
        int ynext = y+dir[i][1];
        if(xnext<0||xnext>=fiji.size()||ynext<0||ynext>=fiji[0].size()) continue;
        if(fiji[xnext][ynext]==0) continue;
        if(visited[xnext][ynext]==false&&fiji[xnext][ynext]==1){
            dfs(fiji,visited,xnext,ynext,mark,count);
        }
 
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> fiji(n,vector<int>(m,0));
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>fiji[i][j];
        }
    }
 
    vector<vector<bool>> visited(n,vector<bool>(m,0));
    int mark=2;
    bool isLand = true;
    unordered_map<int,int> map;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(fiji[i][j]==0) isLand=false;
            if(fiji[i][j]==1&&visited[i][j]==false){
                int count=0;
                dfs(fiji,visited,i,j,mark,count);
                map[mark]=count;
                mark++;
            }
        }
    }
 
    if(isLand==true){
        cout<<n*m;
        return 0;
    }
 
    int result =0;
    int area=0;
    unordered_set<int> addedArea;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            addedArea.clear();
            if(fiji[i][j]==0){
                area = 0;
                for(int k=0;k<4;k++){
                    int inext=dir[k][0]+i;
                    int jnext=dir[k][1]+j;
                    if(inext<0||inext>=fiji.size()||jnext<0||jnext>=fiji[0].size()) continue;
                    if(addedArea.count(fiji[inext][jnext])!=0) continue;
                    area+=map[fiji[inext][jnext]];
                    addedArea.insert(fiji[inext][jnext]);
                }
            }
            result=max(area,result);
        }
    }
    cout<<result+1<<endl;
}

.

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

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

相关文章

5.0 VisionPro调用USB相机的方法与步骤说明(一)

本文介绍如何在C#中调用visionPro以处理USB相机采集到的图片。示例如下: 主要思路如下: 1. 使用AForge来打开以及采集usb相机照片。 usb相机处于一直运行状态。每隔100ms采集一次照片。且触发一次事件。 public void Start() { this.videoSourcePlayer.Stop(); …

微信小程序计算属性与监听器:miniprogram-computed

小程序框架没有提供计算属性相关的 api &#xff0c;但是官方为开发者提供了拓展工具库 miniprogram-computed。 该工具库提供了两个功能&#xff1a; 计算属性 computed监听器 watch 一、安装 miniprogram-computed 在项目的根目录下&#xff0c;使用如下命令&#xff0c;…

强大的AI网站推荐(第二集)—— V0.dev

网站&#xff1a;V0.dev 号称&#xff1a;前端开发神器&#xff0c;专为开发人员和设计师设计&#xff0c;能够使用 AI 生成 React 代码 博主评价&#xff1a;生成的UI效果太强大了&#xff0c;适合需要快速创建UI原型的设计师和开发者 推荐指数&#xff1a;&#x1f31f;&…

整理和总结微信小程序的高频知识点

前言 近期萌生了一些想法&#xff0c;感觉可以做一个小程序作为产出。 但小程序做得比较少&#xff0c;因此边做边复习。整理和总结了一些高频知识点和大家一起分享。 一、模板和组件 1.1模板&#xff08;Template&#xff09; 优势 简单灵活&#xff1a;模板定义和使用都较…

vue中js简单创建一个事件中心/中间件/eventBus

vue中js简单创建一个事件中心/中间件/eventBus 目录结构如下&#xff1a; eventBus.js class eventBus {constructor() {this.events {};}// 监听事件on(event, callback) {if (!this.events[event]) {this.events[event] [];}this.events[event].push(callback);}// 发射…

# [RPA] 使用八爪鱼进行高效网页数据采集

在许多行业中&#xff0c;数据是核心资产。然而&#xff0c;虽然许多网站的文本内容可以免费访问&#xff0c;但手动一条一条采集&#xff0c;不仅耗时耗力&#xff0c;还容易出错。这种情况下&#xff0c;使用自动化工具来提高采集效率就显得尤为重要。本文将介绍 八爪鱼 这一…

K8S学习之基础三十七:prometheus监控node资源

Prometheus v2.2.1 ​ 编写yaml文件&#xff0c;包含创建ns、configmap、deployment、service # 创建monitoring空间 vi prometheus-ns.yaml apiVersion: v1 kind: Namespace metadata:name: monitor-sa# 创建SA并绑定权限 kubectl create serviceaccount monitor -n monito…

#mapreduce打包#maven:could not resolve dependencies for project

打包报错&#xff1a; #报错信息&#xff1a; [ERROR] Failed to execute goal on project mapreduce_teacher1: Could not resolve dependencies for project org.example:mapreduce_teacher1:jar:1.0-SNAPSHOT: Failed to collect dependencies at org.apache.hive:hive-exe…

QT软件匠心开发,塑造卓越设计服务

在当今这个数字化飞速发展的时代&#xff0c;软件已经成为我们生活中不可或缺的一部分。而QT&#xff0c;作为一款跨平台的C图形用户界面应用程序开发框架&#xff0c;凭借其强大的功能和灵活性&#xff0c;在众多软件开发工具中脱颖而出。我们深知&#xff0c;在软件开发领域&…

田间机器人幼苗视觉检测与护苗施肥装置研究(大纲)

田间机器人幼苗视觉检测与护苗施肥装置研究 基于多光谱视觉与精准施肥的农业机器人系统设计 第一章 绪论 1.1 研究背景与意义 农业智能化需求&#xff1a; 传统幼苗检测依赖人工&#xff0c;效率低且易遗漏弱苗/病苗施肥不精准导致资源浪费和环境污染 技术挑战&#xff1a;…

生物化学笔记:医学免疫学原理 免疫系统的组成与功能+克隆选择学说

免疫系统的组成与功能 克隆选择学说 克隆选择学说&#xff08;Clonal Selection Theory&#xff09;是免疫学的核心理论之一&#xff0c;由 麦克法兰伯内特&#xff08;Frank Macfarlane Burnet&#xff09; 在 1957 年提出&#xff0c;用于解释特异性免疫反应的机制。 基本概…

Android 15 获取网络切片信息的标准接口

相关术语 简称全称中文说明URSPUE Route Selection Policy用户路由选择策略URSP 是 5G 核心网(PCF)下发给 UE 的策略,用于指导应用流量如何路由到不同的网络切片或 PDU 会话。其包含多个规则,每条规则由 优先级、业务描述符(Traffic Descriptor) 和 路由选择描述符(Rout…

使用【docker】+【shell】脚本半自动化部署微服务项目

一.前言 以下是一个基于 ‌Docker Shell脚本‌ 的半自动化部署方案&#xff0c;包含镜像构建、容器管理、网络配置和日志监控等核心功能&#xff0c;适用于大多数Web应用或微服务项目。 二‌.目录结构 三.脚本代码实现 1.‌Shell脚本实现 (deploy.sh) #!/bin/bash# 设置颜…

使用 GitHub 可重用工作流和 GitHub Actions 简化 DevOps

在当今的 DevOps 环境中&#xff0c;自动化是开发团队能够更快地交付功能并维护高质量代码库的关键。这就是像 GitHub Actions 这样的工具变得不可或缺的地方&#xff0c;因为它能够直接在存储库中自动化、自定义和执行 GitHub 工作流程。 当然&#xff0c;随着项目的规模和存…

Sql Server 索引性能优化 分析以及分表

定位需优化语句 根据工具 skywking 或者开启慢查询日志 找到 慢sql 的语句根据 执行过程 来 判断 慢的原因 row filter 指标 看查了多少数据 比例多少 type 看下是单表 还是 join联表 比如 执行步骤多 没索引 优化方向 减少执行次数索引 没索引考虑加索引 加索引 尽量选择 i…

vue使用element-ui自定义样式思路分享【实操】

前言 在使用第三方组件时&#xff0c;有时候组件提供的默认样式不满足我们的实际需求&#xff0c;需要对默认样式进行调整&#xff0c;这就需要用到样式穿透。本篇文章以vue3使用element-ui的Tabs组件&#xff0c;对Tabs组件的添加按钮样式进行客制化为例。 确定需要修改的组…

PowerBI 条形图,解决数据标签在条形内部看不清的问题

比如下面的条形图&#xff1a; 最上面两行&#xff0c;数据标签显示在了条形内部&#xff0c;哪怕设置了值为黑色 字体也会自动切换为白色&#xff0c;如果设计要求条形的颜色是浅色&#xff0c;就会导致数据看不清晰。 解决方法一&#xff1a; 将数据标签位置设置为端外 效果…

下载与快速上手 NVM:Node.js 版本管理工具

一、准备工作&#xff1a;卸载旧版 Node.js 重要提示&#xff1a;在安装 NVM 前&#xff0c;请先彻底删除已安装的 Node.js&#xff0c;避免路径冲突&#xff1a; 检查安装路径 bash where node常见路径&#xff1a; C:\Program Files\nodejs\C:\Users\用户名\AppData\Local\n…

网络防火墙(Firewall)、Web防火墙(WAF)、入侵检测系统(IDS)、入侵防御系统(IPS)对比总结

目录 一、Firewall、WAF、IDS、IPS四种设备简介 二、Firewall、WAF、IDS、IPS四种设备的角色定位 三、防火墙&#xff08;Firewall&#xff09;与入侵检测系统&#xff08;IPS&#xff09;的区别 四、入侵检测系统&#xff08;IDS&#xff09;与入侵防御系统&#xff08;IP…

Unity | 游戏数据配置

目录 一、ScriptableObject 1.创建ScriptableObject 2.创建asset资源 3.asset资源的读取与保存 二、Excel转JSON 1.Excel格式 2.导表工具 (1)处理A格式Excel (2)处理B格式Excel 三、解析Json文件 1.读取test.json文件 四、相关插件 在游戏开发中,策划…