0
点赞
收藏
分享

微信扫一扫

全球变暖dfs+bfs(python)

树下的老石头 2022-03-23 阅读 52

文章目录

全球变暖

题目描述
你有一张某海域 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)

通过截图

在这里插入图片描述

如有错误,敬请指正,欢迎交流,谢谢♪(・ω・)ノ

举报

相关推荐

0 条评论