蓝桥云课——全球变暖 Python(深度优先遍历)

 题目地址:全球变暖


此题为“寻找一个解”,又是这种图形式的,所以我们使用深度优先遍历DFS。

        全题思路:题目中所求的是照片中有多少岛屿会被完全淹没,即全部的岛屿 - 留下的岛屿,所以我们可以for循环遍历所有点,对每个点进行判断此点是否在为未淹没的岛屿上,并在循环的同时记录原本有多少个岛屿。


1.先写入数据和模板:

n = int(input())
highlands = 0  # 高地,代表不能被淹没
islands = 0  # 所有的岛屿
note = [[0] * n for _ in range(n)]  # 设置临时数组
picture = []
move = [[1, 0], [-1, 0], [0, 1], [0, -1]]  # 进行上下左右移动
for i in range(n):
    picture.append(input())

def DFS(x, y):
    pass

for x in range(1,n - 1):
    for y in range(1, n - 1):
        if picture[x][y] == '#' and note[x][y] == 0:
            DFS(x, y)

print(islands - highlands)

2.对于是否为高地的判断较为简单,判断此点上下左右均为‘#’即可:

if picture[x + 1][y] == '#' and picture[x - 1][y] == '#' and picture[x][y + 1] == '#' and picture[x][y - 1] == '#':  # 找到高地
    highlands += 1

3.对点进行回溯遍历:

for i in range(4):
    xx = x + move[i][0]
    yy = y + move[i][1]
    if picture[xx][yy] == '#' and note[xx][yy] == 0:  # 若此点为陆地且未被访问过
        DFS(xx, yy)

4.对代码进行补充:

n = int(input())
highlands = 0
islands = 0
note = [[0] * n for _ in range(n)]
picture = []
move = [[1, 0], [-1, 0], [0, 1], [0, -1]]
for i in range(n):
    picture.append(input())

def DFS(x, y):
    global highlands
    if note[x][y] == 1:
        return
    note[x][y] = 1  # 记录已经遍历过
    if picture[x + 1][y] == '#' and picture[x - 1][y] == '#' and picture[x][y + 1] == '#' and picture[x][y - 1] == '#':  # 找到高地
        highlands += 1
    for i in range(4):
        xx = x + move[i][0]
        yy = y + move[i][1]
        if picture[xx][yy] == '#' and note[xx][yy] == 0:
            DFS(xx, yy)
        

for x in range(1,n - 1):
    for y in range(1, n - 1):
        if picture[x][y] == '#' and note[x][y] == 0:
            DFS(x, y)


print(islands - highlands)

5.补充后会发现我们只是找到了高地,但是对于全部岛屿的数量我们并没有找到,但如果在DFS函数内寻找原来全部的岛屿并不好找,所以我们在函数外来寻找,此时我们注意到下面两层for循环中是遍历picture的,当其进入循环时即代表找到了一做岛屿,不管其是否能被淹没,所以:

for x in range(1,n - 1):
    for y in range(1, n - 1):
        if picture[x][y] == '#' and note[x][y] == 0:
            islands += 1
            DFS(x, y)

此时还不能AC,因为在回溯的过程中,highlands点不止存在一个,可能一个岛屿上存在多个highlands点,所以我们提前设立flag来确认此岛屿是否能被淹没。

n = int(input())
highlands = 0
islands = 0
note = [[0] * n for _ in range(n)]
flag = 0  # 防止回溯时重复确认highlands,1代表不能被淹没,0代表能被淹没
picture = []
move = [[1, 0], [-1, 0], [0, 1], [0, -1]]
for i in range(n):
    picture.append(input())

def DFS(x, y):
    global flag
    global highlands
    if note[x][y] == 1:
        return
    note[x][y] = 1  # 记录已经遍历过
    if flag == 0:  # 判断其是否能被淹没
        if picture[x + 1][y] == '#' and picture[x - 1][y] == '#' and picture[x][y + 1] == '#' and picture[x][y - 1] == '#':  # 找到高地
            highlands += 1
            flag = 1  # 不能被淹没,当再次在此岛屿遍历时不必再寻找highlands点
    for i in range(4):
        xx = x + move[i][0]
        yy = y + move[i][1]
        if picture[xx][yy] == '#' and note[xx][yy] == 0:
            DFS(xx, yy)
        

for x in range(1,n - 1):
    for y in range(1, n - 1):
        if picture[x][y] == '#' and note[x][y] == 0:
            islands += 1
            flag = 0  # 假设其能够被淹没
            DFS(x, y)


print(islands - highlands)

为什么在确认flag=1后不能直接return呢?因为即使确定了我们也要将此岛屿的其他点遍历一遍,防止下一次for循环再次遍历这座已经遍历过的岛屿,导致islands过多

此时能够AC了吗?并不能,你会发现有两个案例会出现段错误,经过一个多小时的寻找发现,Python自身存在默认递归深度≈1000,但是1000的深度完全不够此题深度,所以我们在最前面改变其默认递归深度:

import sys
sys.setrecursionlimit(1000000)  # 将递归深度改为1000000

完整AC代码:

sys.setrecursionlimit(1000000)  # 修改深度限制,否则会出现段错误!!!
n = int(input())
highlands = 0
islands = 0
note = [[0] * n for _ in range(n)]
flag = 0  # 防止回溯时重复确认highlands
picture = []
move = [[1, 0], [-1, 0], [0, 1], [0, -1]]
for i in range(n):
    picture.append(input())

def DFS(x, y):
    global flag
    global highlands
    if note[x][y] == 1:
        return
    note[x][y] = 1  # 记录已经遍历过
    if flag == 0:
        if picture[x + 1][y] == '#' and picture[x - 1][y] == '#' and picture[x][y + 1] == '#' and picture[x][y - 1] == '#':  # 找到高地
            highlands += 1
            flag = 1
    for i in range(4):
        xx = x + move[i][0]
        yy = y + move[i][1]
        if picture[xx][yy] == '#' and note[xx][yy] == 0:
            DFS(xx, yy)
        

for x in range(1,n - 1):
    for y in range(1, n - 1):
        if picture[x][y] == '#' and note[x][y] == 0:
            islands += 1
            flag = 0
            DFS(x, y)


print(islands - highlands)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值