当前位置: 首页 > article >正文

代码随想录算法训练营第五十二天|KM101.孤岛的总面积|KM102.沉没孤岛|KM103.水流问题|KM104.建造最大岛屿

101. 孤岛的总面积

direction = [[1, 0], [-1, 0], [0, 1], [0, -1]]
result = 0

def dfs(grid, y, x):
    grid[y][x] = 0
    global result
    result += 1

    for i, j in direction:
        next_x = x + j
        next_y = y + i
        if (next_x < 0 or next_y < 0 or
                next_x >= len(grid[0]) or next_y >= len(grid)
        ):
            continue
        if grid[next_y][next_x] == 1 and not visited[next_y][next_x]:
            visited[next_y][next_x] = True
            dfs(grid, next_y, next_x)

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

for i in range(n):
    grid.append(list(map(int, input().split())))

# 处理边界
for j in range(m):
    # 上边界
    if grid[0][j] == 1 and not visited[0][j]:
        visited[0][j] = True
        dfs(grid, 0, j)
    # 下边界
    if grid[n - 1][j] == 1 and not visited[n - 1][j]:
        visited[n - 1][j] = True
        dfs(grid, n - 1, j)

for i in range(n):
    # 左边界
    if grid[i][0] == 1 and not visited[i][0]:
        visited[i][0] = True
        dfs(grid, i, 0)
    # 右边界
    if grid[i][m - 1] == 1 and not visited[i][m - 1]:
        visited[i][m - 1] = True
        dfs(grid, i, m - 1)

# 计算孤岛总面积
result = 0  # 初始化

for i in range(n):
    for j in range(m):
        if grid[i][j] == 1 and not visited[i][j]:
            visited[i][j] = True
            dfs(grid, i, j)

# 输出孤岛的总面积
print(result)

102. 沉没孤岛

思路:

        从地图周边出发,将周边空格相邻的陆地都做上标记,然后在遍历一遍地图,遇到 陆地 且没做过标记的,那么都是地图中间的 陆地 ,全部改成水域就行。

方法:直接改陆地为其他特殊值作为标记的方式进行;

        步骤一:深搜或者广搜将地图周边的 1 (陆地)全部改成 2 (特殊标记)

        步骤二:将水域中间 1 (陆地)全部改成 水域(0)

        步骤三:将之前标记的 2 改为 1 (陆地)

def dfs(grid, x, y):
    grid[x][y] = 2
    directions = [[-1, 0], [0, -1], [1, 0], [0, 1]]
    for dx, dy in directions:
        next_x, next_y = x + dx, y + dy
        # 超过边界
        if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
            continue
        if grid[next_x][next_y] == 0 or grid[next_x][next_y] == 2:
            continue
        dfs(grid, next_x, next_y)

def main():
    n, m = map(int, input().split())
    grid = [[False] * m for _ in range(n)]
    # 步骤一
    # 从左侧边,和右侧边,向中间遍历
    for i in range(n):
        if grid[i][0] == 1:
            dfs(grid, i, 0)
        if grid[i][m-1] == 1:
            dfs(grid, i, m-1)
    # 从上边和下边,向中间遍历
    for j in range(m):
        if grid[0][j] == 1:
            dfs(grid, 0, j)
        if grid[n-1][j] == 1:
            dfs(grid, n-1, j)
    # 步骤二、步骤三
    for i in range(n):
        for j in range(m):
            if grid[i][j] == 1:
                grid[i][j] = 0
            if grid[i][j] == 2:
                grid[i][j] == 1
    # 打印结果
    for row in grid:
        print(' '.join(map(str, row)))

if __name__ == '__main__':
    main()

103. 水流问题

想法:遍历每个点,然后看这个点能不能同时到达第一组边界和第二组边界

优化方法:没想到,也有待理解,只按照题解敲了代码

first = set()
second = set()
directions = [[-1, 0], [0, 1], [1, 0], [0, -1]]


def dfs(i, j, graph, visited, side):
    if visited[i][j]:
        return

    visited[i][j] = True
    side.add((i, j))

    for x, y in directions:
        new_x = i + x
        new_y = j + y
        if (
                0 <= new_x < len(graph)
                and 0 <= new_y < len(graph[0])
                and int(graph[new_x][new_y]) >= int(graph[i][j])
        ):
            dfs(new_x, new_y, graph, visited, side)


def main():
    global first
    global second

    N, M = map(int, input().strip().split())
    graph = []
    for _ in range(N):
        row = input().strip().split()
        graph.append(row)

    # 是否可到达第一边界
    visited = [[False] * M for _ in range(N)]
    for i in range(M):
        dfs(0, i, graph, visited, first)
    for i in range(N):
        dfs(i, 0, graph, visited, first)

    # 是否可到达第二边界
    visited = [[False] * M for _ in range(N)]
    for i in range(M):
        dfs(N - 1, i, graph, visited, second)
    for i in range(N):
        dfs(i, M - 1, graph, visited, second)

    # 可到达第一边界和第二边界
    res = first & second

    for x, y in res:
        print(f"{x} {y}")


if __name__ == "__main__":
    main()

104. 建造最大岛屿

要求:最多可以将矩阵中的一格水变为一块陆地;

思路:遍历地图尝试 将每一个 0 改成1,然后去搜索地图中的最大的岛屿面积;

优化思路:用一次深搜把每个岛屿的面积记录下来就好;

        第一步:一次遍历地图,得出各个岛屿的面积,并做编号记录。可以使用map记录,key为岛屿编号,value为岛屿面积

        第二步:再遍历地图,遍历0的方格(因为要将0变成1),并统计该1(由0变成的1)周边岛屿面积,将其相邻面积相加在一起,遍历所有 0 之后,就可以得出 选一个0变成1 之后的最大面积。

 本题没有理解,暂时放一放;

from typing import List
from collections import defaultdict

class Solution:
    def __init__(self):
        self.direction = [(1,0),(-1,0),(0,1),(0,-1)]
        self.res = 0
        self.count = 0
        self.idx = 1
        self.count_area = defaultdict(int)

    def max_area_island(self, grid: List[List[int]]) -> int:
        if not grid or len(grid) == 0 or len(grid[0]) == 0:
            return 0

        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1:
                    self.count = 0
                    self.idx += 1
                    self.dfs(grid,i,j)
        # print(grid)
        self.check_area(grid)
        # print(self.count_area)
        
        if self.check_largest_connect_island(grid=grid):
            return self.res + 1
        return max(self.count_area.values())
    
    def dfs(self,grid,row,col):
        grid[row][col] = self.idx
        self.count += 1
        for dr,dc in self.direction:
            _row = dr + row 
            _col = dc + col 
            if 0<=_row<len(grid) and 0<=_col<len(grid[0]) and grid[_row][_col] == 1:
                self.dfs(grid,_row,_col)
        return

    def check_area(self,grid):
        m, n = len(grid), len(grid[0])
        for row in range(m):
            for col in range(n):
                  self.count_area[grid[row][col]] = self.count_area.get(grid[row][col],0) + 1
        return

    def check_largest_connect_island(self,grid):
        m, n = len(grid), len(grid[0])
        has_connect = False
        for row in range(m):
            for col in range(n):
                if grid[row][col] == 0:
                    has_connect = True
                    area = 0
                    visited = set()
                    for dr, dc in self.direction:
                        _row = row + dr 
                        _col = col + dc
                        if 0<=_row<len(grid) and 0<=_col<len(grid[0]) and grid[_row][_col] != 0 and grid[_row][_col] not in visited:
                            visited.add(grid[_row][_col])
                            area += self.count_area[grid[_row][_col]]
                            self.res = max(self.res, area)
                            
        return has_connect




def main():
    m, n = map(int, input().split())
    grid = []

    for i in range(m):
        grid.append(list(map(int,input().split())))

    
    sol = Solution()
    print(sol.max_area_island(grid))

if __name__ == '__main__':
    main()


http://www.kler.cn/a/466301.html

相关文章:

  • 企业级网络运维管理系统深度解析与实践案例
  • memcached的基本使用
  • 【赵渝强老师】MongoDB写入数据的过程
  • 电子应用设计方案86:智能 AI背景墙系统设计
  • Linux vi/vim 编辑器:功能强大的文本处理工具
  • Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(3):配置备用数据库
  • SQLite简介:轻量级数据库入门
  • 57.在 Vue 3 中使用 OpenLayers 点击选择 Feature 设置特定颜色
  • 断舍离:通往心灵自由的五级阶梯
  • JavaScript系列(4)--数值类型专题
  • js获取下拉单选框的值和显示的值
  • springboot整合Quartz实现定时任务
  • 趣味编程:心形曲线
  • Linux环境(CentOs7) 安装 Node环境
  • 最近学习shader的一些总结
  • npm ERR! ECONNRESET 解决方法
  • Celeborn Spark 集成最新进展
  • 滤波器的主要参数
  • Flutter路由钩子
  • 1月2日作业
  • 酒店管理系统|Java|SSM|VUE| 前后端分离
  • [文献阅读] Reducing the Dimensionality of Data with Neural Networks
  • 查找最长回文子串
  • 七种改进爬山算法的方法
  • 阿里巴巴Java 面试突击手册开源(涵盖 p5-p8 技术栈)
  • 数据结构排序