本题为“地图版”+“过程版”递归问题。
题目描述
有一个大小是N*M的战场地图,被墙壁“#”分割成大小不同的区域,上下左右四个方向相邻的空地‘.’属于同一个区域,只有空地上可能存在‘E’,请求出地图上总共有多少区域里敌人数小于K。
输入
第一行输入N,M,K
N表示地图的行数
M表示地图的列数
K表示目标敌人的数量
N, M<=100
最后为一个N*M的数组
输出
敌人数小于K的区域的数量
示例1
输入
3 5 2
…#EE
E.#E.
###.
输出
1
说明
总共有两个区域,左边区域有一个敌人,右边区域有3个敌人。只有左边区域满足小于2个敌人的要求
解题思路及代码
- 本次递归可能有多个起点,故需在函数外面套一个循环。
- 每次递归函数的调用表示调查一个区域,根据每个区域返回的E的数量判断是否符合题目要求。
代码如下(示例):
n, m, k = list(map(int, input().split()))
way = [[] for _ in range(n)]
for i in range(n):
s = list(input())
way[i] = s
def dfs(x, y):
global now
if x < 0 or x == n or y < 0 or y == m or way[x][y] == '#':
return
if way[x][y] == 'E':
now += 1
way[x][y] = '#'
dfs(x + 1, y)
dfs(x - 1, y)
dfs(x, y + 1)
dfs(x, y - 1)
return
now = 0
res = 0
for i in range(n):
for j in range(m):
if way[i][j] != '#':
dfs(i, j)
res += 1 if now < k else 0
now = 0 # 一个区域找完后需要把敌人数清零
print(res)
总结
回顾整个递归流程可以发现,递归函数往往比较抽象。所以,我们需要结合实际情况进行理解,不能生搬硬套。