python蓝桥杯:有一块农田被划分为N*M块,农作物和杂草分布生长在农田中?

Python010

python蓝桥杯:有一块农田被划分为N*M块,农作物和杂草分布生长在农田中?,第1张

思路:先将输入的数据保存成二维字符串矩阵或者0,1矩阵,方便后续统计。然后可以使用并查集或者dfs统计四个方向上相邻的农田 返回独立的农田区域数量

以深搜举例:先转换成0/1矩阵(1表示农田0表示杂草)然后遍历矩阵当遇到值为1的坐标进行dfs,ans+1 遍历结束返回ans

部分python代码:

m = len(arr)

n = len(arr[0])

ans = 0

def dfs(i,j):

arr[i][j] = 0

for x,y in [[i+1,j],[i-1,j],[i,j+1],[i,j-1]]:

if not(0<=x<m and 0<=y<n) or arr[x][y] ==0:

continue

dfs(x,y)

for i in range(m):

for j in range(n):

if arr[i][j] == 1:

dfs(i,j)

ans += 1

return ans

题目描述

给你一个大小为 m x n 的二进制矩阵 grid,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。

一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

示例 1:

示例 2:

提示:

根据飞地的定义,如果从一个陆地单元格出发无法移动到网格边界,则这个陆地单元格是飞地。因此可以将所有陆地单元格分成两类:第一类陆地单元格和网格边界相连,这些陆地单元格不是飞地;第二类陆地单元格不和网格边界相连,这些陆地单元格是飞地。

我们可以从网格边界上的每个陆地单元格开始深度优先搜索,遍历完边界之后,所有和网格边界相连的陆地单元格就都被访问过了。然后遍历整个网格,如果网格中的一个陆地单元格没有被访问过,则该陆地单元格不和网格的边界相连,是飞地。

代码实现时,由于网格边界上的单元格一定不是飞地,因此遍历网格统计飞地的数量时只需要遍历不在网格边界上的单元格。

代码

Java

C#

C++

C

Python3

Golang

JavaScript

复杂度分析

也可以通过广度优先搜索判断每个陆地单元格是否和网格边界相连。

首先从网格边界上的每个陆地单元格开始广度优先搜索,访问所有和网格边界相连的陆地单元格,然后遍历整个网格,统计飞地的数量。

代码

Java

C#

C++

C

Python3

Golang

JavaScript

复杂度分析

除了深度优先搜索和广度优先搜索的方法以外,也可以使用并查集判断每个陆地单元格是否和网格边界相连。

并查集的核心思想是计算网格中的每个陆地单元格所在的连通分量。对于网格边界上的每个陆地单元格,其所在的连通分量中的所有陆地单元格都不是飞地。如果一个陆地单元格所在的连通分量不同于任何一个网格边界上的陆地单元格所在的连通分量,则该陆地单元格是飞地。

并查集的做法是,遍历整个网格,对于网格中的每个陆地单元格,将其与所有相邻的陆地单元格做合并操作。由于需要判断每个陆地单元格所在的连通分量是否和网格边界相连,因此并查集还需要记录每个单元格是否和网格边界相连的信息,在合并操作时更新该信息。

在遍历网格完成并查集的合并操作之后,再次遍历整个网格,通过并查集中的信息判断每个陆地单元格是否和网格边界相连,统计飞地的数量。

代码

Java

C#

C++

C

Python3

Golang

JavaScript

复杂度分析

BY /

本文作者:力扣