输入一个只包含0和1的二维数组,上下左右和对角相邻的1组成一个区块,0不形成区块,求数组中的区块个数。
输入格式
第一行输入两个正整数N和M,N表示数组行数,M表示数组列数。
接下来N行,每行表示数组对应的一行,每行包含M个整数,整数之间用空格隔开。
输出格式
输出一个整数,表示数组中区块的个数。
数据范围
0 ≤ N, M, N∗M ≤ 10^6
输入样例:
3 3
0 1 0
1 0 0
1 0 1
输出样例:
2
样例解释
数组右下角的1单独构成一个区块,其他的3个1对角或上下相邻,构成另一个区块。
思路一: 二维数组进行 dfs
n,m = list(map(eval,input().split(' ')))
matrix = []
for _ in range(n):
matrix += input().split(' '),
3 3
0 1 0
1 0 0
1 0 1
# 定义上下左右对角线的方位
dx = [-1, -1, -1, 0, 0, 1, 1, 1]
dy = [-1, 0, 1, -1, 1, -1, 0, 1]
res = 0
def dfs(i, j):
matrix[i][j] = 0
for k in range(len(dx)):
x, y = i + dx[k], j + dy[k]
if x>=0 and y>=0 and x<n and y<m and matrix[x][y] == '1':
dfs(x, y)
for i in range(n):
for j in range(m):
if matrix[i][j] == '1':
res += 1
dfs(i, j)
print(res)
2
思路二:由于题目中的矩阵的长宽没有给定,在 C/C++ 语言中,最好是定义指定大小的数组,如果存在 10^6 * 10^6 的数组,会出现爆栈情况,所以这里有个小技巧,使用一维数组来保存题目的二位数组。
那么在二维数组的元素下标为 i,j
时,对应的一维数组元素下标应该是 i*m+j
一维数组的元素下标为 k
时,对应的二维数组元素下标应该是 k//m, k%m
n,m = list(map(eval,input().split(' ')))
matrix = []
for _ in range(n):
matrix += input().split(' ')
3 3
1 1 1
0 1 0
1 0 1
matrix
['1', '1', '1', '0', '1', '0', '1', '0', '1']
res = 0
def dfs(x, y):
matrix[x * m + y] = 0
for i in range(-1, 2):
for j in range(-1, 2):
a, b = x+i, y+j
if a >= 0 and a < n and b >= 0 and b < m and matrix[a * m + b] == '1':
dfs(a, b)
for i in range(n):
for j in range(m):
if matrix[i * m + j] == '1':
res += 1
dfs(i, j)
print(res)
1