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

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

需强化知识点

  • 103,104 优化思路

题目

101. 孤岛的总面积

  • 此处 area 多余
python 复制代码
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 且没被访问过的,即为孤岛
python 复制代码
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,然后根据其最终是否能到达边界位置,返回布尔值
  • 优化思路:从边界出发,逆流而上,最终不能被访问到的地方为结果
python 复制代码
# 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的情况
python 复制代码
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()
相关推荐
能工智人小辰23 分钟前
Codeforces Round 509 (Div. 2) C. Coffee Break
c语言·c++·算法
kingmax5421200824 分钟前
CCF GESP202503 Grade4-B4263 [GESP202503 四级] 荒地开垦
数据结构·算法
岁忧29 分钟前
LeetCode 高频 SQL 50 题(基础版)之 【高级字符串函数 / 正则表达式 / 子句】· 上
sql·算法·leetcode
eachin_z1 小时前
力扣刷题(第四十九天)
算法·leetcode·职场和发展
闻缺陷则喜何志丹1 小时前
【强连通分量 缩点 拓扑排序】P3387 【模板】缩点|普及+
c++·算法·拓扑排序·洛谷·强连通分量·缩点
机器学习之心2 小时前
机器学习用于算法交易(Matlab实现)
算法·机器学习·matlab
AL流云。2 小时前
【优选算法】C++滑动窗口
数据结构·c++·算法
qq_429879673 小时前
省略号和可变参数模板
开发语言·c++·算法
飞川撸码4 小时前
【LeetCode 热题100】网格路径类 DP 系列题:不同路径 & 最小路径和(力扣62 / 64 )(Go语言版)
算法·leetcode·golang·动态规划
Neil今天也要学习4 小时前
永磁同步电机参数辨识算法--IPMSM拓展卡尔曼滤波全参数辨识
单片机·嵌入式硬件·算法