代码随想录算法营Day57 | 孤岛的总面积,沉没孤岛,水流问题,建造最大岛屿

孤岛的总面积

这道题先将靠近边界线上的岛屿都放置为0,然后再用深度或者广度搜索算法去计算剩余的孤岛总面积

count = 0
position = [[1, 0], [0, 1], [-1, 0], [0, -1]]
def dfs(matrix,x,y):
    global count
    matrix[x][y] = 0
    count += 1
    for i,j in position:
        next_x = x + i
        next_y = y + j
        if next_x < 0 or next_y < 0 or next_x >= len(matrix) or next_y >= len(matrix[0]):
            continue
        if matrix[next_x][next_y] == 1:
            dfs(matrix,next_x,next_y)
    
N,M = map(int,input().split())
matrix = []
for _ in range(N):
    matrix.append(list(map(int,input().split())))

for i in range(N):
    if matrix[i][0] == 1:
        dfs(matrix,i,0)
    if matrix[i][M-1] == 1:
        dfs(matrix,i,M-1)
    
for j in range(M):
    if matrix[0][j] == 1:
        dfs(matrix,0,j)
    if matrix[N-1][j] == 1:
        dfs(matrix,N-1,j)
count=0
for i in range(N):
    for j in range(M):
        if matrix[i][j] == 1:
            dfs(matrix,i,j)
print(count)

沉没孤岛

这道题思路和上面一样,不过这里需要将边界上的岛屿变成2。那么此时矩阵当中就只有靠近边界上的2以及孤岛1。这时候只需要将所有数值为2或者为1的都减去1即可。

position = [[1, 0], [0, 1], [-1, 0], [0, -1]]
def dfs(matrix,x,y):
    matrix[x][y] = 2
    for i,j in position:
        next_x = x + i
        next_y = y + j
        if next_x < 0 or next_y < 0 or next_x >= len(matrix) or next_y >= len(matrix[0]):
            continue
        if matrix[next_x][next_y] == 1:
            dfs(matrix,next_x,next_y)
    
N,M = map(int,input().split())
matrix = []
for _ in range(N):
    matrix.append(list(map(int,input().split())))

for i in range(N):
    if matrix[i][0] == 1:
        dfs(matrix,i,0)
    if matrix[i][M-1] == 1:
        dfs(matrix,i,M-1)
    
for j in range(M):
    if matrix[0][j] == 1:
        dfs(matrix,0,j)
    if matrix[N-1][j] == 1:
        dfs(matrix,N-1,j)
count=0
for i in range(N):
    for j in range(M):
        if matrix[i][j] == 1 or matrix[i][j] == 2:
            matrix[i][j] -= 1
            
for l in matrix:
    print(" ".join(map(str,l)))

水流问题

现有一个 N × M 的矩阵,每个单元格包含一个数值,这个数值代表该位置的相对高度。矩阵的左边界和上边界被认为是第一组边界,而矩阵的右边界和下边界被视为第二组边界。

矩阵模拟了一个地形,当雨水落在上面时,水会根据地形的倾斜向低处流动,但只能从较高或等高的地点流向较低或等高并且相邻(上下左右方向)的地点。我们的目标是确定那些单元格,从这些单元格出发的水可以达到第一组边界和第二组边界。

这道题我们从各边界逆着往内去找可达的路径,然后取这两个可达路径的交集即可。

N,M = map(int,input().split())
matrix = []
for _ in range(N):
    matrix.append(list(map(int,input().split())))

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

def dfs(i,j,grid,visited,side):
    if visited[i][j]:
        return
    visited[i][j] = True
    side.add((i,j))
    for x,y in directions:
        new_x = x + i
        new_y = y + j
        if 0<= new_x < N and 0<= new_y < M and grid[i][j] <= grid[new_x][new_y]:
            dfs(new_x,new_y,grid,visited,side)

visited = [[False] * M for _ in range(N)]
for i in range(N):
    dfs(i,0,matrix,visited,first)
for j in range(M):
    dfs(0,j,matrix,visited,first)

visited = [[False] * M for _ in range(N)]
for i in range(N):
    dfs(i,M-1,matrix,visited,second)
for j in range(M):
    dfs(N-1,j,matrix,visited,second)

res = first & second

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


建造最大岛屿

这道题先将各个岛用不同的数字标示出来,并计算每个岛的面积,而后遍历每个海水记录可以由该海水块连接起来的陆地的最大面积。

N,M = map(int,input().split())
matrix = []
for _ in range(N):
    matrix.append(list(map(int,input().split())))

directions = [[-1, 0], [0, 1], [0, -1], [1, 0]]
area = 0

def dfs(i,j,grid,visited,num):
    global area

    if visited[i][j]:
        return
    
    visited[i][j] = True
    grid[i][j] = num
    area += 1
    for x, y in directions:
        new_x = x + i
        new_y = y + j
        if 0 <= new_x < N and 0 <= new_y < M and grid[new_x][new_y] == 1:
            dfs(new_x,new_y,grid,visited,num)

cnt = 2
visited = [[False] * M for _ in range(N)]
rec = {}
for i in range(N):
    for j in range(M):
        if matrix[i][j] == 1:
            area = 0
            dfs(i,j,matrix,visited,cnt)
            rec[cnt] = area
            cnt += 1

res = 0
for i in range(N):
    for j in range(M):
        if matrix[i][j] == 0:
            max_island = 1
            v = set()
            for x, y in directions:
                new_x = x + i
                new_y = y + j
                if 0 <= new_x < N and 0 <= new_y < M and matrix[new_x][new_y] != 0 and matrix[new_x][new_y] not in v:
                    max_island += rec[matrix[new_x][new_y]]
                    v.add(matrix[new_x][new_y])
            res = max(res,max_island)
if res == 0:
    print(max(rec.values()))
else:
    print(res)


你可能感兴趣的:(算法,python,leetcode)