当前位置: 首页 > news >正文

代码随想录算法训练营Day-50 图论02 | 99.岛屿数量-深搜、99.岛屿数量-广搜 、100.岛屿的最大面积

99.岛屿数量-深搜

主函数比较朴素:定义基础变量,接收数据,遍历图节点,对每个节点进行处理:遇到没访问过的陆地就result++,然后深搜这篇陆地的上下左右,把和这片土地挨着的所有土地标记为访问过,也就是把一片岛屿都标记为访问过,之后再遍历到这片岛屿的其他陆地节点时就直接跳过了。遍历完之后,把所有的新大陆计数并搜索成岛屿,最后结果就是岛屿数量了。

深搜函数:有两种写法

一种是,终止条件显示写出,也就是终止条件判断节点是否访问过以及是否是陆地,如果不是陆地或者被访问过,那么就return,作为终止条件,然后在函数逻辑里面只进行下一个节点(上下左右)是否越界的判断;

(其实也可以把越界判断也放在终止条件里,也就是一开始判断x,y是否越界,下面递归逻辑里的下一个节点就不需要进行判断了。

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

一种是,终止条件隐式在递归逻辑里面,由于只有符合条件(索引不越界,坐标是陆地且未被访问)的节点才会被送入下一层递归,所以其实相当于隐含了终止条件。

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

99.岛屿数量-广搜

广搜的主函数逻辑和深搜没变化,主要是搜索岛屿的逻辑有一些区别。

广搜岛屿:首先定义队列,然后把起点入队,将入队坐标立刻标记为访问过(因为入队坐标就是“待搜索周围四方向的中心坐标”,因此它本身肯定访问过),然后循环直到队为空,首先获取队头并弹出,然后执行四个方向遍历,判断新坐标是否越界,是否是陆地且未访问过,一旦满足就入队,并立刻将坐标标记为访问过。

注:标记为访问过一定要在入队以后,而不是出队时,否则会让节点重复入队,浪费时间。

#include<iostream> using namespace std; #include<vector> #include<queue> int dir[4][2]={0,1,1,0,-1,0,0,-1}; void bfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y){ queue<pair<int,int>> qe; qe.push({x,y}); visited[x][y]=true; while(!qe.empty()){ pair<int,int> pr = qe.front();qe.pop(); for(int i=0;i<4;i++){ int nextx = pr.first+dir[i][0]; int nexty = pr.second+dir[i][1]; if(nextx<0 || nextx>=grid.size() || nexty<0 || nexty>=grid[0].size()) continue; if(grid[nextx][nexty]==1 && visited[nextx][nexty]==false){ qe.push({nextx,nexty}); visited[nextx][nexty] = true; } } } } int main(){ int n,m; cin>>n>>m; vector<vector<int>> grid(n,vector<int>(m)); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>grid[i][j]; } } vector<vector<bool>> visited(n,vector<bool>(m,false)); int result=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(grid[i][j]==1 && visited[i][j]==0){ result++; bfs(grid, visited, i, j); } } } cout<<result<<endl; }

100.岛屿的最大面积

本题就是在深搜或者广搜函数里加一个计数变量,每标记一个岛屿中的新陆地时就加1,搜索完之后计数就达到了岛屿的面积。

注意在main函数调用搜索函数之前,要先把当前遍历到的坐标也就是起点先标记为访问过,然后将计数变量初始化为1,因为岛屿的面积是从1开始,也就是至少为1。

#include<iostream> using namespace std; #include<vector> int dir[4][2]={0,1,1,0,-1,0,0,-1}; void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y, int& count){ for(int i=0;i<4;i++){ int nextx = x+dir[i][0]; int nexty = y+dir[i][1]; if(nextx<0 || nextx>=grid.size() || nexty<0 || nexty>=grid[0].size()) continue; if(grid[nextx][nexty]==1 && visited[nextx][nexty]==false){ visited[nextx][nexty] = true; count++; dfs(grid, visited, nextx, nexty, count); } } } int main(){ int n,m; cin>>n>>m; vector<vector<int>> grid(n,vector<int>(m)); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>grid[i][j]; } } vector<vector<bool>> visited(n,vector<bool>(m,false)); int result=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(grid[i][j]==1 && visited[i][j]==0){ visited[i][j] = true; int newnum = 1; dfs(grid, visited, i, j, newnum); result = max(result,newnum); } } } cout<<result<<endl; }

http://www.jsqmd.com/news/819333/

相关文章:

  • 基于Node.js的静态博客生成器:从零构建自动化内容流水线
  • 从英文恐惧到设计自信:一个产品设计师的Axure中文界面改造之旅
  • RS-485与RS-422工业通信技术详解与应用实践
  • SciDownl终极指南:5步高效获取学术文献的完整教程
  • 脚本的下一站:让自然语言直接成为可执行入口
  • 运维系列【仅供参考】:Git提交邮箱配置全攻略:从全局到本地仓库的灵活设置(附GitHub关联技巧)
  • 基于ROACH2平台的VLBI数字后端系统设计与实现
  • Perplexity搜索ACM结果不排序?揭秘影响因子加权算法逆向工程,自定义排序脚本已开源
  • 程序员的职业地图:从入门到架构师的全路径规划
  • copy4ai:专为AI工作流设计的智能复制工具,解决网页内容格式粘贴难题
  • 写论文软件哪个好?2026 全新实测:真文献 + 实证 + 全流程,虎贲等考 AI 成毕业论文最优解
  • 基于Claude的模块化代码生成框架:多代理协作开发实践
  • 代码生成引擎Loom:模板+数据驱动,自动化生成高质量代码
  • 2026年new四川服装定制市场优选:专业厂商深度实力解析 - 2026年企业推荐榜
  • 自由职业者收入追踪器:从数据模型到可视化分析的全栈实现
  • 如何用模块化架构实现200+小说网站的智能下载:novel-downloader技术深度解析
  • 从零构建本地AI编程助手:Mervelas的隐私优先架构与Bun技术栈实践
  • FPGA时序约束基础与优化:False Path与Multicycle Path详解
  • 如何用安卓虚拟摄像头解决视频会议和直播中的隐私与创意难题?
  • 猫抓cat-catch浏览器扩展:专业级资源嗅探与下载解决方案
  • 开源记忆增强系统mnemo-cortex:开发者的命令行知识管理利器
  • 嵌入式测试学习第 10天:主控、外设、传感器、通信模块
  • AI手机新突破!端侧智能体提速1.6倍,纯软件框架
  • 从零构建YesWeAreBot:基于规则引擎的智能对话机器人实战
  • 干掉 IDEA!Cursor3 发布,VSCode 那套 IDE 过时了!
  • ChatGPT 5.4 与 5.4 mini 深度解析:旗舰实力与轻量高效怎么选
  • AI代理自动化LinkedIn广告管理:从规则引擎到机器学习优化
  • 2026年安徽锌钢护栏采购指南:如何甄选靠谱厂家 - 2026年企业推荐榜
  • 博客生成器架构设计:基于LLM与模块化流水线的自动化内容创作实践
  • 动漫线稿上色失控?用--stylize 500+--no “shading, texture noise“双指令锁死干净赛璐珞效果(实测出图成功率提升310%)