蓝桥杯:全球变暖(python,BFS,DFS)(栈溢出的处理办法)

图论的经典题型,深度优先搜索和广度优先搜索都可以,但是本题推荐使用广度优先搜索(类似的题最好都用广度优先搜索),因为使用深度优先搜索会爆栈(栈溢出)。本篇博客两种方法都进行讲解,也会讲解栈溢出的解决方案。

题目:

题目链接:全球变暖
你有一张某海域 N×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:

.......
.##....
.##....
....##.
..####.
...###.
.......

其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 2 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:

.......
.......
.......
.......
....#..
.......
.......

请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

输入格式
第一行包含一个整数N。
以下 N 行 N 列,包含一个由字符”#”和”.”构成的 N×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。

输出格式
一个整数表示答案。

数据范围
1≤N≤1000

输入样例1:

7
.......
.##....
.##....
....##.
..####.
...###.
.......

输出样例1:
1

输入样例2:

9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........

输出样例2:
1

思路:

接触过图论的同学都知道 连通块问题,是基础搜索。用DFS或BFS都行:遍历一个连通块(找到这个连通块中所有的’#‘,并标记已经搜过,不用再搜);再遍历下一个连通块…;遍历完所有连通块,统计有多少个连通块。

本题是在寻找连通块的基础上进行了进阶(问题1),还要找寻被淹没的连通块(问题2)。(这里分步讨论)

问题1很好解决,那么问题2该如何计数呢?

方法一:BFS:

在统计连通块的基础上我们可以定义两个变量 total 和 bound

total 用来统计每个连通块上有多少块土地,

bound 用来统计在每个连通块上有多少土地是紧挨着水的(上,下,左,右任意一边挨水都算),

如果 total = bound 则表明该连通块会完全淹没(因为所有土地都紧靠水)。

这个思路想出来了问题就很好解决了,下面直接套用模板就行

代码及详细注释:

from collections import deque# 输入迷宫大小
n = int(input())
a = []
# 读取迷宫
for i in range(n):path = list(input())a.append(path)# 记录访问情况
vis = [[False] * n for _ in range(n)]
# 定义四个方向
dirs = [[0,1],[0,-1],[1,0],[-1,0]]def bfs(x, y):global total, boundq = deque()vis[x][y] = Trueq.append([x, y])while q:curx, cury = q.popleft()total += 1is_bound = Falsefor dir in dirs:next_x = curx + dir[0]next_y = cury + dir[1]# 边界检查if next_x < 0 or next_y < 0 or next_x >= n or next_y >= n:continue# 已访问过的点跳过if vis[next_x][next_y] == True:continue# 如果是水域,标记为边界点并跳过if a[next_x][next_y] == '.':is_bound = Truecontinuevis[next_x][next_y] = Trueq.append([next_x, next_y])if is_bound:bound += 1cnt = 0
# 遍历整个迷宫
for i in range(n):for j in range(n):# 未访问过的岛屿开始进行搜索if vis[i][j] == False and a[i][j] == '#':total = 0bound = 0bfs(i, j)# 如果所有土地都紧靠水,计数加一if total == bound:cnt += 1print(cnt)

方法二:DFS

dfs解决问题二的时候有个很巧妙的方法,就是在统计连通块的时候多加一个判断语句(判断当前岛屿是否被完全淹没),就是判断上下左右是否为陆地,如果是陆地的话,最后计数不算该连通块。

但是dfs很大的问题就是栈溢出问题,也就是爆栈,虽然 dfs 比 bfs 写起来简单但不太推荐大家在打比赛的时候用(爆栈几率小但也不敢赌啊)

解决爆栈问题也比较简单,对递归深度进行限制即可,使用sys.setrecursionlimit()函数

在Python中,sys.setrecursionlimit()函数用于设置递归深度限制。递归深度指的是递归函数嵌套调用的层数。通过调用sys.setrecursionlimit()函数,可以设置Python解释器允许的最大递归深度,从而避免递归调用导致的栈溢出错误。

代码及详细注释:

import sys
# 设置递归深度限制
sys.setrecursionlimit(60000)# 读取输入的迷宫大小
n = int(input())# 读取迷宫地图
a = []
for i in range(n):path = list(input())a.append(path)# 记录访问状态
vis = [[False] * n for _ in range(n)]# 定义四个方向
dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]# 深度优先搜索函数
def dfs(x, y):global flagvis[x][y] = True# 判断当前岛屿是否被完全淹没if a[x][y + 1] == "#" and a[x][y - 1] == "#" and a[x + 1][y] == "#" and a[x - 1][y] == "#":flag = 1# 遍历四个方向for dir in dirs:next_x = x + dir[0]next_y = y + dir[1]if next_x < 0 or next_y < 0 or next_x >= n or next_y >= n:continueif vis[next_x][next_y] == True:continueif a[next_x][next_y] == '.':continuedfs(next_x, next_y)# 统计未被淹没的岛屿数量
cnt = 0
for i in range(n):for j in range(n):if vis[i][j] == False and a[i][j] == '#':flag = 0dfs(i, j)if flag == 0:cnt += 1
# 输出结果
print(cnt)

总结:

本题看着很简单,但是统计问题解决实现起来还是有点绕的。

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

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

相关文章

【协议】RPC

文章目录 概述与web service/web api/wcf区别简介区别和联系 grpc.Net Core示例 参考 概述 与web service/web api/wcf区别 简介 RPC&#xff08;Remote Procedure Call Protocol&#xff09;即远程过程调用协议&#xff0c;是分布式系统间通信的一种协议。通过网络从远程计…

【Apache Doris】周FAQ集锦:第 2 期

【Apache Doris】周FAQ集锦&#xff1a;第 2 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…

【WEEK6】学习目标及总结【MySQL】【中文版】

学习目标&#xff1a; 两周完成MySQL的学习——第二周 学习内容&#xff1a; 参考视频教程【狂神说Java】MySQL最新教程通俗易懂DQL查询数据 学习时间及产出&#xff1a; 第六周MON~WED, SUN 2024.4.1【WEEK6】 【DAY1】DQL查询数据-第一部分【中文版】【WEEK6】 【DAY1】DQ…

关键字:static

回顾类中的实例变量&#xff08;即非static的成员变量&#xff09; class Circle{ private double radius; public Circle(double radius){ this.radiusradius; } public double findArea(){ return Math.PI*radius*radius; } } 创建两个C…

计算机网络—TCP协议详解:特性、应用(2)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;マリンブルーの庭園—ずっと真夜中でいいのに。 0:34━━━━━━️&#x1f49f;──────── 3:34 &#x1f504; ◀️…

FPGA的就业前景

FPGA&#xff08;Field-Programmable Gate Array&#xff09;技术在数字电路设计和嵌入式系统开发方面具有广泛的应用&#xff0c;因此在FPGA领域有着较好的就业前景。 目前&#xff0c;FPGA在通信、计算机、消费电子、汽车、航空航天等行业中得到了广泛应用。随着新一代通信网…

抽象类与抽象方法(或abstract关键字)

由来 举例1&#xff1a; 随着继承层次中一个个新子类的定义&#xff0c;类变得越来越具体&#xff0c;而父类则更一般&#xff0c;更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计得非常抽象&#xff0c;以至于它没有具体的实例&#xff0c;这样的类叫做…

STM32G系 编程连接不上目标板,也有可能是软件不兼容。

由于一直用的老版本STM32 ST-LINK Utility 4.20 &#xff0c;找遍了所有问题&#xff0c;SWD就是连不上目标板。 电源脚 VDDA 地线&#xff0c;SWD的四条线&#xff0c;还是不行&#xff0c;浪费了一天&#xff0c;第二天才想起&#xff0c;是不是G系升级了 SWD协议。结果下载…

[InternLM训练营第二期笔记]2. 轻松分钟玩转书生·浦语大模型趣味 Demo

该系列是上海AI Lab举行的书生 浦语大模型训练营的相关笔记部分。 该笔记是第二节课&#xff0c;完成对话、多模态等demo&#xff0c;形成对InternLM的初步了解 1. 部署InternLM2-Chat-1.8B InternLM2-Chat-1.8B是一个对话小模型&#xff0c;只有1.8B参数&#xff0c;因此运行…

【算法刷题day15】Leetcode:各种层序遍历、226.翻转二叉树、101. 对称二叉树

文章目录 Leetcode 层序遍历解题思路代码总结 Leetcode 226.翻转二叉树解题思路代码总结 Leetcode 101. 对称二叉树解题思路代码总结 草稿图网站 java的Deque Leetcode 层序遍历 题目&#xff1a;102.二叉树的层序遍历 题目&#xff1a;107. 二叉树的层序遍历 II 题目&#xf…

深度学习:神经网络模型的剪枝和压缩简述

深度学习的神经网路的剪枝和压缩&#xff0c;大致的简述&#xff0c; 主要采用&#xff1a; network slimming&#xff0c;瘦身网络... 深度学习网络&#xff0c;压缩的主要方式&#xff1a; 1.剪枝&#xff0c;nerwork pruing&#xff0c; 2.稀疏表示&#xff0c;sparse rep…

【Git】分支协同开发

1、前言 由于之前一直是在master上开发 没有分支开发过 接触过好几个项目组 远程仓库不是用码云就是 gitlab 然后几个人在master开发 也没有UAT分支这些 没有分支协同开发很容易把冲突 读完本文 你将对Git分支开发又有一个新的认识 2、概念 master和UAT在远程都是保护分支…

每日面经分享(python进阶 part2)

Python中的装饰器和上下文管理器区别是什么&#xff1f;它们分别适用于哪些场景&#xff1f; a. 装饰器用于在函数或类的外部添加额外功能&#xff0c;而上下文管理器用于管理资源的获取和释放。 b. 装饰器是一种用于修改函数或类行为的技术。适用于需要在函数或类的外部添加额…

鸿蒙实战开发-通过输入法框架实现自绘编辑框

介绍 本示例通过输入法框架实现自会编辑框&#xff0c;可以绑定输入法应用&#xff0c;从输入法应用输入内容&#xff0c;显示和隐藏输入法。 效果预览 使用说明 1.点击编辑框可以绑定并拉起输入法&#xff0c;可以从输入法键盘输入内容到编辑框。 2.可以点击attach/dettac…

【学习分享】小白写算法之冒泡排序篇

【学习分享】小白写算法之冒泡排序篇 前言一、什么是冒泡排序算法二、冒泡排序算法如何实现三、C语言实现算法四、复杂度计算五、算法稳定性六、小结 前言 最近我要学习下数据结构和算法&#xff0c;有兴趣的小伙伴可以点个关注&#xff0c;一起学习。争取写的浅显易懂。如果你…

解决Toad for Oracle显示乱中文码问题

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

数据结构记录

之前记录的数据结构笔记&#xff0c;不过图片显示不了了 数据结构与算法(C版) 1、绪论 1.1、数据结构的研究内容 一般应用步骤&#xff1a;分析问题&#xff0c;提取操作对象&#xff0c;分析操作对象之间的关系&#xff0c;建立数学模型。 1.2、基本概念和术语 数据&…

CANoe自带的TCP/IP协议栈中TCP的keep alive机制是如何工作的

TCP keep alive机制我们已经讲过太多次,车内很多控制器的TCP keep alive机制相信很多开发和测试的人也配置或者测试过。我们今天想知道CANoe软件自带的TCP/IP协议栈中TCP keep alive机制是如何工作的。 首先大家需要知道TCP keep alive的参数有哪些?其实就三个参数:CP_KEEP…

Qt QML的枚举浅用

QML的枚举用法 序言概念命名规则在QML定义枚举的规范 用法QML的枚举定义方法供QML调用的&#xff0c;C的枚举定义方法 序言 概念 QML的枚举和C的其实差不多&#xff0c;但是呢&#xff0c;局限比较多&#xff0c;首先不能在main.qml里定义&#xff0c;也不能在子项中定义。 …

C++语言学习(二)——⭐缺省参数、函数重载、引用

1.⭐缺省参数 &#xff08;1&#xff09;缺省参数概念 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时&#xff0c;如果没有指定实参则采用该形参的缺省值&#xff0c;否则使用指定的实参。 void Func(int a 0) {cout<<a<<endl; } int…