文章目录
全球变暖
题目描述
你有一张某海域 NxN 像素的照片,"."表示海洋、"#"表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有 2 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入描述
第一行包含一个整数 N (1≤N≤1000)。
以下 N 行 N 列代表一张海域照片。
照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。
输出一个整数表示答案。
输入输出样例
示例
输入
7
.......
.##....
.##....
....##.
..####.
...###.
.......
输出
1
运行限制
最大运行时间:1s
最大运行内存: 256M
分析
- 这题题意大概就是说:岛屿就是连通块。
这里我题意一直理解为需要有上下左右的陆地才是岛屿 - 用flag标记是否淹没(0:淹没,1:没有淹没),初始状态都定为被淹没,如果周围都是陆地(四个方向),那么这个岛必定不会沉,改写flag的状态。
- 对四个方向进行搜索,注意搜索
必须是没走过的
,并且是陆地。如果没注意已经搜索过的话,程序应该跳不出去。像下图的5块陆地所示。 注意递归的深度
,蓝桥在提交的时候直接跟我说无效的返回。。。。
- 后续的二维遍历中,没走过和陆地这两个判断条件,将找到该陆地的连通块,可以保证有且只有一次遍历到该连通块。
运行代码(dfs)
import sys
sys.setrecursionlimit(1000000)
def dfs(x,y):
global flag
vis[x][y] = 1 # 标记走过
if mp[x][y-1] == '#' and mp[x][y+1] == '#' and mp[x-1][y] == '#' and mp[x+1][y] == '#':
flag = 1 # 标记没有淹没
for i in range(4):
new_x = x + dic[i][0]
new_y = y + dic[i][1]
if vis[new_x][new_y] == 0 and mp[new_x][new_y] == '#':
dfs(new_x,new_y)
n = int(input())
# 构建地图
mp = []
for i in range(n):
mp.append(list(input()))
vis = [[0]*n for _ in range(n)]
dic = [(0,-1),(0,1),(-1,0),(1,0)] # 上下左右
res = 0
for i in range(n):
for j in range(n):
if mp[i][j] == '#' and vis[i][j] == 0:
flag = 0
dfs(i,j)
if flag == 0:
res+=1
print(res)
通过截图
分析
- 不得不说,dfs和bfs真的很像。dfs遍历的下一个是由当前位置上下左右探测到的点,bfs遍历的下一个是弹出点的上下左右。
- 注意:由于dfs新的坐标会重新执行dfs,所以
vis在最上方
进行标记,但bfs,进来的时候需要一次标记,每次添加新坐标
也需要标记。 - 剩下原理就基本一致了
运行代码(bfs)
from collections import deque
def bfs(x,y):
dic = [(0,1),(0,-1),(1,0),(-1,0)] # 方向
q = deque() # 双端队列
q.append((x,y)) # 添加坐标
vis[x][y]=1
global flag
while q:
t = q.popleft() # 经典弹出
tx,ty = t[0],t[1]
if mp[tx][ty+1]=='#' and mp[tx][ty-1]=='#' and mp[tx+1][ty]=='#' and mp[tx-1][ty]=='#':
flag = 1
for i in range(4):
new_x = tx+dic[i][0]
new_y = ty+dic[i][1]
if vis[new_x][new_y]==0 and mp[new_x][new_y]=="#":
q.append((new_x,new_y))
vis[new_x][new_y]=1
n = int(input())
mp =[]
for i in range(n):
mp.append(list(input()))
vis = []
for i in range(n):
vis.append([0]*n)
ans = 0
for i in range(n):
for j in range(n):
if vis[i][j]==0 and mp[i][j]=="#":
flag = 0
bfs(i,j)
if flag == 0:
ans+=1
print(ans)
通过截图
如有错误,敬请指正,欢迎交流,谢谢♪(・ω・)ノ