Skip to content

M12558: 岛屿周长

matrices, dfs, http://cs101.openjudge.cn/pctbook/M12558

用一个n * m的二维数组表示地图,1表示陆地,0代表海水,每一格都表示一个1*1的区域。地图中的格子只能横向或者纵向连接(不能对角连接),连接在一起的陆地称作岛屿,同时整个地图都被海水围绕。假设给出的地图中只会有一个岛屿,并且岛屿中不会有湖(即不会有水被陆地包围的情况出现)。请判断所给定的二维地图中岛屿的周长。

输入

第一行为n和m,表示地图的大小(1<=n<=100, 1<=m<=100)。接下来n行,每行有m个数,分别描述每一格的数值。数值之间均用空格隔开。

输出

只有一行,即岛屿的周长(正整数)。

样例输入

3 4
1 1 1 0
0 1 0 0
1 1 0 0

样例输出

14

来源:cs10116 final exam

解题思路:注意到正方形周长为 4,并且每个方向与其他正方形相连则少条边,直接加保护圈,写公式,遍历一遍,直接完成。

思路:某个陆地格子对周长的贡献值是 4-周围的陆地数,其余的就是普通二维数组、加保护圈。

python
n,m = map(int,input().split())
l = [[0]*(m+2)] +[[0] +list(map(int,input().split()))+[0] for _ in range(n)]+[[0]*(m+2)]
ans = 0
for i in range(1,n+1):
    for j in range(1, m + 1):
        if l[i][j] == 1:
            ans += 4-l[i+1][j]-l[i][j+1]-l[i-1][j]-l[i][j-1]
print(ans)

思路:用总长度减去接触消失的长度即可,块数乘4-接触边乘2即可。

python
# 王沛然,24物理学院
n,m=map(int,input().split())
k=0
sl=[]
for _ in range(n):
    sl.append(list(map(int,input().split())))
for i in range(n):
    for j in range(m):
        if sl[i][j]==1:
            k+=4
            if i<n-1 and sl[i+1][j]==1:
                k-=2
            if j<m-1 and sl[i][j+1]==1:
                k-=2
print(k)

dfs思路:

给矩阵加上保护圈,预存四个方向,遍历矩阵上为1的点,处理过的点设为-1跳过,该点周边(遍历四个方向)的点(判断在矩阵范围内)为0时,周长加一,为1时递推

python
n, m = map(int, input().split())

# 初始化地图,外层加了一圈0
the_map = [[0] * (m + 2) for _ in range(n + 2)]
for i in range(1, n + 1):
    the_map[i][1:-1] = list(map(int, input().split()))

directions = [(-1, 0), (0, -1), (1, 0), (0, 1)]
count = 0

def dfs(x, y):
    global count
    the_map[x][y] = -1  # 标记为已访问
    for dx, dy in directions:
        nx, ny = x + dx, y + dy
        if 0 <= nx < n + 2 and 0 <= ny < m + 2:
            if the_map[nx][ny] == 0:
                count += 1
            elif the_map[nx][ny] == 1:
                dfs(nx, ny)

# 遍历地图,从每个1开始进行DFS
for i in range(1, n + 1):
    for j in range(1, m + 1):
        if the_map[i][j] == 1:
            dfs(i, j)

print(count)

解题思路:画一画就能发现,上下左右只要有0就周长+1。记得加保护圈0。

python
n, m = map(int, input().split())
A = []
A.append([0 for i in range(m+2)])
for i in range(n):
    A.append([0] + [int(x) for x in input().split()] + [0])
A.append([0 for i in range(m+2)])

ans = 0
for i in range(1, n+1):
    for j in range(1, m+1):
        if A[i][j] == 1:
            if A[i-1][j]==0:
                ans += 1
            if A[i+1][j]==0:
                ans += 1
            if A[i][j-1]==0: 
                ans += 1
            if A[i][j+1]==0:
                ans += 1
print(ans)
python
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
n, m = map(int, input().split())
a = [[0]*(m+2)]+[[0]+[int(x) for x in input().split()]+[0] for _ in 
range(n)]+[[0]*(m+2)]
c = 0
for i in range(1, n+1):
    for j in range(1, m+1):
        if a[i][j] == 1:
            for k in range(4):
                if a[i+dx[k]][j+dy[k]] == 0:
                    c += 1
print(c)

dfs

python
#gpt
def dfs(grid, i, j):
    if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]) or grid[i][j] == 0:
        return 1
    if grid[i][j] == -1:
        return 0

    grid[i][j] = -1  # 标记已经访问过的陆地

    perimeter = 0
    perimeter += dfs(grid, i + 1, j)
    perimeter += dfs(grid, i - 1, j)
    perimeter += dfs(grid, i, j + 1)
    perimeter += dfs(grid, i, j - 1)

    return perimeter

def islandPerimeter(grid):
    perimeter = 0
    for i in range(len(grid)):
        for j in range(len(grid[0])):
            if grid[i][j] == 1:
                perimeter = dfs(grid, i, j)
                break
    return perimeter

# 读取输入
n, m = map(int, input().split())
grid = []
for _ in range(n):
    row = list(map(int, input().split()))
    grid.append(row)

# 调用函数计算岛屿周长并输出结果
print(islandPerimeter(grid))

bfs,

python
from collections import deque

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

def edge(x,y):
    count = 0
    for dx, dy in directions:
        if x+dx < 0 or y+dy < 0 or x+dx >= n or y+dy >= m:
            count += 1
        else:
            if grid[x+dx][y+dy] == 0:
                count += 1
    return count

def discover(x,y):
    perimeter = edge(x,y)
    land = deque()
    land.append((x,y))
    discovered[x][y] = True
    while land:
        x, y = land.popleft()
        for dx, dy in directions:
            nx, ny = x+dx, y+dy
            if 0<=nx<n and 0<=ny<m and not discovered[nx][ny] and grid[nx][ny] == 1:
                land.append((nx,ny))
                discovered[nx][ny] = True
                perimeter += edge(nx,ny)
    return perimeter

for i in range(n):
    for j in range(m):
        if grid[i][j] == 1:
            print(discover(i,j))
            exit()