Flood Fill——AcWing 1097. 池塘计数

Flood Fill

定义

Flood Fill算法,又称为洪水填充或种子填充算法,是一种在图或网格数据结构中探索连通区域的搜索算法。它从一个初始节点(种子点)开始,将具有相同属性(如颜色、值等)的相邻节点递归或迭代地标记或改变属性值,直到遍历完所有与种子点连通且满足条件的节点。该算法因其形象地模拟了洪水填满低洼地带的过程而得名。

运用情况

  1. 图形编辑软件:用于实现颜色填充工具,用户点击图像上的一点后,相同颜色的相邻区域会被填充上新的颜色。
  2. 游戏开发:在游戏地图编辑或UI设计中,快速改变特定区域的颜色或纹理。
  3. 计算机视觉与图像处理:在图像分割、物体识别中,标识或隔离特定区域。
  4. 数据分析与可视化:在数据集上标记相连的相同值区域,帮助数据分析和可视化。
  5. 路径规划与地图绘制:在网格地图中寻找并标记可达区域或障碍区域。

注意事项

  1. 递归深度限制:使用递归实现时,需警惕栈溢出风险,可通过设置递归深度限制或改用迭代方法避免。
  2. 边界检查:确保算法不会超出数据结构的边界,避免访问未定义或非法内存区域。
  3. 效率与空间优化:利用访问标志数组减少重复访问,使用广度优先搜索(BFS)相比深度优先搜索(DFS)可能在空间效率上有优势。
  4. 颜色相似度判断:在某些应用场景中,可能需要基于颜色差异阈值来决定是否填充相邻像素。
  5. 并发处理:在并行或分布式系统中实施时,需要适当的锁机制或任务划分策略以避免冲突。

解题思路

  1. 初始化:选择起始节点(种子点)和目标属性值(如颜色)。
  2. 选择搜索策略:决定使用DFS还是BFS。DFS更易于实现但可能导致较深的递归调用;BFS则更适合求解最短路径问题,且在大多数情况下空间效率较高。
  3. 创建工作队列/栈:根据所选策略准备数据结构来存储待处理节点。
  4. 标记与扩展:将种子点标记为已访问,并将其相邻且属性相同的节点加入队列/栈。
  5. 循环处理:循环执行以下步骤直至队列/栈为空:从队列/栈中取出一个节点,修改其属性(如颜色),并将符合条件的相邻未访问节点加入队列/栈。
  6. 结束条件:当所有与种子点连通且符合条件的节点都被处理过后,算法结束。

AcWing 1097. 池塘计数

题目描述

AcWing 1097. 池塘计数 - AcWing

运行代码

#include <iostream>
#include <vector>
using namespace std;
int n, m;
vector<vector<char>> grid;
void dfs(int i, int j) {if (i < 0 || i >= n || j < 0 || j >= m || grid[i][j]!= 'W') {return;}grid[i][j] = '.';dfs(i - 1, j);dfs(i + 1, j);dfs(i, j - 1);dfs(i, j + 1);dfs(i - 1, j - 1);dfs(i + 1, j + 1);dfs(i - 1, j + 1);dfs(i + 1, j - 1);
}
int countPonds() {int ponds = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (grid[i][j] == 'W') {ponds++;dfs(i, j);}}}return ponds;
}
int main() {cin >> n >> m;grid.resize(n, vector<char>(m));for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {cin >> grid[i][j];}}cout << countPonds() << endl;return 0;
}

代码思路

  1. 输入处理:

    • 首先,读取网格的行数n和列数m
    • 然后,根据nm的值,初始化一个二维向量grid来存储地图信息。每一行是一个包含m个元素的字符向量,表示地图的一行。
    • 接着,逐行读取每个单元格的状态(字符),填充到grid中。
  2. 深度优先搜索(DFS):

    • 定义函数dfs(int i, int j),用于从地图上的位置(i, j)开始,遍历并标记相连的所有水池单元格。它通过递归地访问当前点的上、下、左、右以及对角线相邻的点,如果那些点是水池(即字符为'W'),则标记为已访问(改为'.')并继续深入搜索。
    • 注意这里考虑了八个方向的邻居,包括水平、垂直和两个对角线方向,实现了对角落和边缘连接的全面搜索。
  3. 计算水汽数量:函数countPonds()遍历整个网格,每当遇到一个未被访问的水池(字符'W'),就调用dfs()函数进行填充,并累加计数器ponds。这样,最终的ponds值就是地图中独立水池的数量。

  4. 输出结果:主函数最后输出计算得到的水汽数量。

改进思路

  1. 使用迭代而非递归:深度优先搜索虽然逻辑直观,但是递归可能会导致较大的栈空间消耗,特别是对于大型网格。可以通过使用栈数据结构来实现迭代版本的DFS,从而避免栈溢出的风险。

  2. 增加记忆化或标记已访问:尽管代码中通过将'W'改为'.'来标记已访问,但这种做法改变了原始地图。可以引入一个额外的二维布尔数组visited[n][m]来记录每个位置是否已被访问过,这样既不影响原地图,也能有效避免重复访问,提高效率。

  3. 广度优先搜索(BFS)替代DFS:在某些情况下,使用BFS代替DFS可能更有利,特别是当需要按距离排序(比如找出最近的水池)或者关心最短路径时。BFS使用队列进行层次遍历,可以更容易地控制搜索的范围和顺序。

  4. 并行处理:如果网格非常大,可以考虑将网格分割成多个小块,并在不同的线程或进程中并行执行DFS或BFS,最后汇总结果。但需要注意同步访问共享资源,防止数据竞争。

  5. 优化搜索方向:在某些特定场景下,不是所有八个方向都需要检查。例如,如果知道水体只能水平或垂直流动(非对角线),则可以减少搜索方向,提高效率。

  6. 使用并查集数据结构:对于频繁的连通性查询,使用并查集可以在合并连通分量时提供高效的O(α(n))操作(其中α(n)是一个非常接近于1的函数),有助于提升处理大量连通组件的效率。

  7. 动态调整搜索范围:根据具体问题,可能不需要全面八方向搜索。例如,如果水域只能在平面上水平或垂直流动,可以只检查上下左右四个方向。

其它代码

#include <iostream>
#include <cstring>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n, m;
int ans;
char g[N][N];
PII p[N * N];
bool st[N][N];
void bfs(int sx, int sy)
{int hh = 0, tt = -1;p[++ tt] = {sx, sy};st[sx][sy] = true;while(hh <= tt){PII t = p[hh ++];for(int i = t.x - 1; i <= t.x + 1; i ++ )for(int j = t.y - 1; j <= t.y + 1; j ++ ){if(i < 0 || i >= n || j < 0 || j >= m) continue;if(st[i][j] || g[i][j] == '.') continue;st[i][j] = true;p[++ tt] = {i, j};}}
}
int main()
{cin >> n >> m;for(int i = 0; i < n; i ++ ) cin >> g[i];for(int i = 0; i < n; i ++ )for(int j = 0; j < m; j ++ )if(!st[i][j] && g[i][j] == 'W'){bfs(i, j);ans ++ ;}cout << ans << endl;return 0;
}

代码思路

  1. 数据结构与变量定义:

    • 使用#define宏定义了坐标对的引用方式,便于后续操作。
    • 定义了常量N作为最大行数/列数的限制,以及二维数组g来存储地图信息,布尔型二维数组st来标记某个位置是否已经被访问过。
    • PII是一个类型别名,表示一对整数(坐标),用于存储队列中的位置信息。
    • ans变量用来累计水池的数量。
  2. 主函数(main):

    • 首先读取地图的行数n和列数m,然后逐行读取地图信息到二维数组g中。
    • 双重循环遍历整个地图,对于每一个未访问且为水池的格子,调用bfs函数进行广度优先搜索,同时增加水池计数器ans的值。
  3. 广度优先搜索(bfs)函数:

    • 初始化队列,将当前水池的起始坐标(sx, sy)入队,并标记为已访问。
    • 当队列不为空时,循环处理队首元素,遍历其周围的8个相邻格子(注意代码中实际访问了9个位置,包括自身,但注释掉的那行代码表明本意是排除自身)。
    • 对于每个有效的相邻格子(未越界且未访问且为水池),将其标记为已访问,并将其坐标入队。
    • 这一过程会持续到当前水池区域的所有可达位置都被访问过,从而完成了单个水池的计数。
  4. 输出结果:最后,输出统计到的水池总数ans

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

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

相关文章

P4. 微服务: 匹配系统(下)

P4. 微服务: 匹配系统 下 0 概述1 游戏同步系统1.1 游戏同步的设计1.2 游戏同步的实现 2 匹配系统微服务的实现2.1 微服务概述2.2 匹配系统接口url的实现2.3 微服务之间的通信2.4 匹配逻辑的实现2.5 匹配系统的权限控制 3 bug的解决3.1 自己匹配自己3.2 断开连接问题 0 概述 本…

大数据之Linux部署常用命令脚本封装

文章目录 编写集群命令执行脚本xcall集群命令执行1. 脚本需求2. 需求分析3. 脚本实现3.1 创建脚本存放目录3.2 编写xcall脚本3.3 修改脚本执行权限3.4 测试脚本 编写集群分发脚本xsync集群分发脚本1. 脚本需求2. 需求分析3. 脚本实现3.1 创建脚本存放目录3.2 编写xsync脚本3.3 …

计算机毕业设计PyFlink+Spark+Hive民宿推荐系统 酒店推荐系统 民宿酒店数据分析可视化大屏 民宿爬虫 民宿大数据 知识图谱 机器学习

本科毕业设计(论文) 开题报告 学院 &#xff1a; 计算机学院 课题名称 &#xff1a; 民宿数据可视化分析系统的设计与实现 姓名 &#xff1a; 庄贵远 学号 &#xff1a; 2020135232 专业 &#xff1a; 数据科学与大数据技术 班级 &#xff1a; 20大数据本科2…

重温react-06(初识函数组件和快速生成格式的插件使用方式)

开始 函数组件必然成为未来发展的趋势(个人见解),总之努力的去学习,才能赚更多的钱.加油呀! 函数组件的格式 import React from reactexport default function LearnFunction01() {return (<div>LearnFunction01</div>) }以上是函数式组件的组基本的方式 快捷生…

基于DSMM数据安全能力建设方案的落地性评估指标

写在前面&#xff1a; 随着信息技术的迅猛发展&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;数据安全问题也随之而来&#xff0c;如何确保数据的安全性、完整性和可用性&#xff0c;已成为企业面临的重要挑战。DSMM&#xff08;数据安全能力成熟度模型&#x…

混合专家模型(MoE)的前世今生

在文章《聊聊最近很火的混合专家模型&#xff08;MoE&#xff09;》中&#xff0c;我们简单介绍了MoE模型的定义和设计&#xff0c;并且比较了MoE和Dense模型的区别&#xff0c;今天我们继续来回顾一下MoE模型发展的历史和最新的发展现状。 从去年GPT-4发布至今&#xff0c;MoE…

[C++][设计模式][中介者模式]详细讲解

目录 1.动机2.模式定义3.要点总结 1.动机 在软件构建过程中&#xff0c;经常会出现多个对象相互关联的情况&#xff0c;对象之间常常会维持一种复杂的引用关系&#xff0c;如果遇到一些需求的更改&#xff0c;这种直接的引用关系将面临不断的变化在这种情况下&#xff0c;可以…

SpringDataJPA系列(2)Commons核心Repository

SpringDataJPA系列(2)Commons核心Repository Spring Data Commons依赖关系 我们通过 Gradle 看一下项目依赖&#xff0c;了解一下 Spring Data Common 的依赖关系 通过上图的项目依赖&#xff0c;不难发现&#xff0c;数据库连接用的是 JDBC&#xff0c;连接池用的是 HikariC…

使用label-studio对OCR数据进行预标注

导读 label-studio作为一款数据标注工具相信大家都不陌生&#xff0c;对于需要进行web数据标注协同来说应该是必备工具了&#xff0c;标注的数据类型很全涉及AI的各个任务(图像、语音、NLP、视频等)&#xff0c;还支持自定义涉及模版。 然而&#xff0c;我们在标注数据的过程…

Veno File Manager(VFM)v4.2.7 中文包整理

Veno File Manager&#xff08;VFM&#xff09;是一个简单灵活的即插即用文件管理器&#xff0c;易于使用且具有许多选项。将文件发送给您的客户&#xff0c;使用专用文件夹创建新用户&#xff0c;或仅用作您的个人文件云。从任何设备访问&#xff0c;用户管理和从直观的管理面…

OpenCV 调用自定义训练的 YOLO-V8 Onnx 模型

一、YOLO-V8 转 Onnx 在本专栏的前面几篇文章中&#xff0c;我们使用 ultralytics 公司开源发布的 YOLO-V8 模型&#xff0c;分别 Fine-Tuning 实验了 目标检测、关键点检测、分类 任务&#xff0c;实验后发现效果都非常的不错&#xff0c;但是前面的演示都是基于 ultralytics…

C语言分支和循环(下)

C语言分支和循环&#xff08;下&#xff09; 1. 随机数生成1.1 rand1.2 srand1.3 time1.4 设置随机数的范围 2. 猜数字游戏实现 掌握了前面学习的这些知识&#xff0c;我们就可以写⼀些稍微有趣的代码了&#xff0c;比如&#xff1a; 写⼀个猜数字游戏 游戏要求&#xff1a; 电…

第6章 复制

文章目录 前言1.配置1.1建立复制1.2断开复制1.3 安全性1.4 只读1.5 传输延迟 2. 拓扑2.1.一主一从结构2.2.一主多从结构2.3.树状主从结构 3.原理3.1复制过程3.2数据同步3.3全量复制 前言 复制功能&#xff0c;实现了相同数据的多个Redis副本。复制功能是高可用Redis的基础&…

智能交通(2)——IntelliLight智能交通灯

论文分享&#xff1a;IntelliLight | Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mininghttps://dl.acm.org/doi/10.1145/3219819.3220096摘要 智能交通灯控制对于高效的交通系统至关重要。目前现有的交通信号灯大多由手…

【Python系列】列表推导式:简洁而强大的数据操作工具

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

已成功与服务器建立连接,但是在登录过程中发生错误。(provider: SSL提供程序,error:0-证书链是由不受信任的颁发机构颁发的。)

已成功与服务器建立连接&#xff0c;但是在登录过程中发生错误。(provider: SSL提供程序,error:0-证书链是由不受信任的颁发机构颁发的。) 在连接SQL Server2008R2数据库时发生错误。 连接字符串&#xff1a;server127.0.0.1;uidsa;pwd1;databasedb; 解决办法&#xff1a; 方…

PySide(PyQt)在图像上画线

1、按鼠标左键任意画线 import sys from PySide6.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget from PySide6.QtGui import QPainter, QPixmap, QMouseEvent, QColor, QPen from PySide6.QtCore import Qt, QPointclass PaintLabel(QLabel):def __init__(self…

如何使用FlowUs打造爆款自媒体内容?内容资产管理沉淀的先进工具选息流

FlowUs 是一款流行的在线协作工具&#xff0c;它以其灵活的块编辑器、看板视图、数据库管理等功能受到众多个人和团队的喜爱。将其应用于内容资产管理&#xff0c;尤其是对于追求打造爆款自媒体的创作者而言&#xff0c;可以极大地提升内容创作、组织、分发及分析的效率。 内容…

无刷直流电机(BLDCM)仿真建模

无刷直流电机&#xff0c;即BLDCM在各个行业应用非常广泛。在汽车电子领域&#xff0c;BLDCM被广泛用于电动汽车、混合动力汽车、电动自行车等车辆的驱动系统中。由于BLDCM具有高效率、高力矩密度和快速响应的优势&#xff0c;它可以提供可靠的动力输出&#xff0c;并且可以通过…

idea常用配置 | 快捷注释

idea快速注释 一、类上快速注释 &#xff08;本方法是IDEA环境自带的&#xff0c;设置特别方便简单易使用&#xff09; 1、偏好设置->编辑器->文件和代码模版 | File-Settings-Editor-File and Code Templates 2、右下方的“描述”中有相对应的自动注注释配置格式 贴…