【代码随想录训练营】【Day 66】【图论-3】| 卡码 101-104

【代码随想录训练营】【Day 66】【图论-3】| 卡码 101-104

需强化知识点

  • 103,104 优化思路

题目

101. 孤岛的总面积

  • 此处 area 多余
def dfs(grid, x, y, area):
    dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
    m, n = len(grid), len(grid[0])
    area[0] += 1
    grid[x][y] = 0
    
    for add_x, add_y in dirs:
        next_x, next_y = x + add_x, y + add_y
        if next_x < 0 or next_x >= m or next_y < 0 or next_y >= n:
            continue
        if grid[next_x][next_y]:
            dfs(grid, next_x, next_y, area)

tmp = list(map(int, input().split()))
m, n = tmp[0], tmp[1]
grid = [[0] * n for _ in range(m)]

for i in range(m):
    tmp = list(map(int, input().split()))
    for j in range(n):
        grid[i][j] = tmp[j]

for i in range(m):
    if grid[i][0]:
        dfs(grid, i, 0, [0])
    if grid[i][n-1]:
        dfs(grid, i, n-1, [0])
        
for j in range(n):
    if grid[0][j]:
        dfs(grid, 0, j, [0])
    if grid[m-1][j]:
        dfs(grid, m-1, j, [0])
        
cur = 0
for i in range(m):
    for j in range(n):
        if grid[i][j]:
            cur += 1

print(cur)          

102. 沉没孤岛

  • 思路:从左右上下边界出发遍历,然后visited数组标记,最后 grid 为 1 且没被访问过的,即为孤岛
import collections

def bfs(grid, visited, x, y):
    dirs = [[1, 0], [0, 1], [-1, 0], [0, -1]]
    m, n = len(grid), len(grid[0])
    
    que = collections.deque()
    que.append([x, y])
    visited[x][y] = True
    
    while que:
        tmp = que.popleft()
        cur_x, cur_y = tmp[0], tmp[1]
    
        for add_x, add_y in dirs:
            next_x, next_y = cur_x + add_x, cur_y + add_y
            if next_x < 0 or next_x >= m or next_y < 0 or next_y >= n:
                continue
            if grid[next_x][next_y] and not visited[next_x][next_y]:
                que.append([next_x, next_y])
                visited[next_x][next_y] = True

tmp = list(map(int, input().split()))
m, n = tmp[0], tmp[1]
grid = [[0] * n for _ in range(m)]
visited = [[False] * n for _ in range(m)]

for i in range(m):
    tmp = list(map(int, input().split()))
    for j in range(n):
        grid[i][j] = tmp[j]

for i in range(m):
    if grid[i][0]:
        bfs(grid, visited ,i, 0)
    if grid[i][n-1]:
        bfs(grid, visited, i, n-1)
        
for j in range(n):
    if grid[0][j]:
        bfs(grid, visited, 0, j)
    if grid[m-1][j]:
        bfs(grid, visited, m-1, j)

for i in range(m):
    for j in range(n):
        if grid[i][j] and not visited[i][j]:
            grid[i][j] = 0

for i in range(m):
    for j in range(n):
        print(grid[i][j], end=" ")
        
    

103. 水流问题

  • 暴力法:直接每个位置 dfs,然后根据其最终是否能到达边界位置,返回布尔值
  • 优化思路:从边界出发,逆流而上,最终不能被访问到的地方为结果
# def dfs(grid, visited, x, y):
#     dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
    
#     m, n = len(grid), len(grid[0])
#     visited[x][y] = True
    
#     for add_x, add_y in dirs:
#         next_x, next_y = x + add_x, y + add_y
#         if next_x < 0 or next_x >= m or next_y < 0 or next_y >= n:
#             continue
#         if grid[x][y] < grid[next_x][next_y]:
#             continue
#         if not visited[next_x][next_y]:
#             dfs(grid, visited, next_x, next_y)

# def isResult(grid, x, y):
#     m, n = len(grid), len(grid[0])
#     visited = [[False] * n for _ in range(m)]
#     dfs(grid, visited, x, y)
#     first_result, second_result = False, False
    
#     for i in range(m):
#         if visited[i][0]:
#             first_result = True
#         if visited[i][n-1]:
#             second_result = True
    
#     for j in range(n):
#         if visited[0][j]:
#             first_result = True
#         if visited[m-1][j]:
#             second_result = True
    
#     return first_result and second_result

# tmp = list(map(int, input().split()))
# m, n = tmp[0], tmp[1]

# grid = [[0] * n for _ in range(m)]
# for i in range(m):
#     tmp = list(map(int, input().split()))
#     for j in range(n):
#         grid[i][j] = tmp[j]


# for i in range(m):
#     for j in range(n):
#         if isResult(grid, i, j):
#             print("{} {}".format(i, j))

def dfs(grid, visited, x, y):
    dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
    
    m, n = len(grid), len(grid[0])
    visited[x][y] = True
    
    for add_x, add_y in dirs:
        next_x, next_y = x + add_x, y + add_y
        if next_x < 0 or next_x >= m or next_y < 0 or next_y >= n:
            continue
        # 等于不行
        if grid[x][y] > grid[next_x][next_y]:
            continue
        if not visited[next_x][next_y]:
            dfs(grid, visited, next_x, next_y)

tmp = list(map(int, input().split()))
m, n = tmp[0], tmp[1]

grid = [[0] * n for _ in range(m)]
for i in range(m):
    tmp = list(map(int, input().split()))
    for j in range(n):
        grid[i][j] = tmp[j]   

visited_first = [[False]*n for _ in range(m)]
visited_second = [[False]*n for _ in range(m)]

for i in range(m):
    dfs(grid, visited_first, i, 0)
    dfs(grid, visited_second, i, n-1)

for j in range(n):
    dfs(grid, visited_first, 0, j)
    dfs(grid, visited_second, m-1, j)


for i in range(m):
    for j in range(n):
        if visited_first[i][j] and visited_second[i][j]:
            print("{} {}".format(i, j))
            

104. 建造最大岛屿

  • 暴力法:直接每个为0的位置,dfs,记录其面积
  • 优化思路:先记录每个岛屿的面积,并编号,然后 每个为0的位置,假设其为1,然后加上周围能访问到岛屿面积
    • 注意周围访问岛屿的去重问题,以及为grid 0的情况
def dfs(grid, mask, x, y, count):
    dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
    
    m, n = len(grid), len(grid[0])
    grid[x][y] = mask
    count[0] += 1
    
    for add_x, add_y in dirs:
        next_x, next_y = x + add_x, y + add_y
        if next_x < 0 or next_x >= m or next_y < 0 or next_y >= n:
            continue
        if grid[next_x][next_y] != 1 :
            continue
        dfs(grid, mask, next_x, next_y, count)


    
def main():
    tmp = list(map(int, input().split()))
    m, n = tmp[0], tmp[1]

    grid = [[0] * n for _ in range(m)]
    for i in range(m):
        tmp = list(map(int, input().split()))
        for j in range(n):
            grid[i][j] = tmp[j]   

    mask = 2
    isAllgrid = True
    gridNum = {}
    for i in range(m):
        for j in range(n):
            if grid[i][j] == 0:
                isAllgrid = False
            if grid[i][j] == 1:
                count = [0]
                dfs(grid, mask, i, j, count)
                gridNum[mask] = count[0]
                mask += 1
            
    if isAllgrid:
        print(m*n)
        return 
    
    result = 0
    dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]]
    for i in range(m):
        for j in range(n):
            if grid[i][j] == 0:
                tmp = 1
                visitedGrid = []
                for add_x, add_y in dirs:
                    next_x, next_y = i + add_x, j + add_y
                    if next_x < 0 or next_x >= m or next_y < 0 or next_y >= n:
                        continue
                    if grid[next_x][next_y] not in visitedGrid and grid[next_x][next_y] != 0:
                        tmp += gridNum[grid[next_x][next_y]]
                        visitedGrid.append(grid[next_x][next_y])
                result = max(result, tmp)
                
    print(result)   

main()

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值