1.题目
2XXX年,人类通过对火星的大气进行宜居改造分析,使得火星已在理论上具备人类宜居的条件,由于技术原因,无法一次性将火星大气全部改造,只能通过局部处理形式,假设将火星待改造的区域为row*column的网格每个网格有3个值,宜居区、可改造区、死一区,使用YES、NO、NA代替,YES表示该网格已经完成大气改造,NO表示该网格未进行改造,后期可进行改造,NA表示死亡区,不作为判断是否改造完成的宜居,无法穿过初始化只下,该区域可能存在多人官居区,并日每人官居区能同时在每人大阳日单位向上下左右四人方向的相邻格子进行扩散,自动将4个方向相邻的真空区改造成宜居区;请计算这个待改造区域的网格中,可改造区是否能全部变成宜居区,如果可以,则返回改造的太阳日天数,不可以则返回-1。
输入描述:
输入row * column个网格数据Q,每个网格值枚举值如下: YES,NO,NA,样例:YES YES NO
NO NO NO
NA NO YES
输出描述:
可改造区是否能全部变成宜居区,如果可以,则返回改造的太阳日天数,不可以则返回-1.
补充说明:
gridi只有3种情况,YES、NO、NA
row == grid.length, column == gridlil.length, 1 <= row, column <= 8
示例1
输入:
YES YES NO
NO NO NO
YES NO NO
输出:
说明: 经过2个太阳日,完成宜居改造
示例2
输入:
YES NO NO NO
NO NO NO NO
NO NO NO NO
NO NO NO NO
输出:
说明: 经过6个太阳日,可完成改造
示例3
输入:
NO NA
输出:
说明:无改造初始条件,无法进行改造
示例4
输入:
YES NO NO YES
NO NO YES NO
NO YES NA NA
YES NO NA NO
输出:
说明: 右下角的区域,被周边三个死亡区挡住,无法实现改造
2.解题思路
这道题目要求你确定一个火星网格区域是否可以通过一系列操作,将所有的可改造区域变成宜居区域,并计算完成这个任务所需的太阳日的天数。
- YES 表示宜居区,表示这个区域已经改造成适合人类居住的状态。
- NO 表示可改造区,这些区域还没有改造成宜居区,但可以通过一系列操作逐渐改造。
- NA 表示死亡区,这些区域无法改造成宜居区,不考虑在内。
接下来,我们来解释上下左右的动作:
在这个问题中,人类可以站在宜居区域,并朝上下左右四个方向之一移动,将相邻的可改造区域改造成宜居区域。换句话说,人类可以从一个宜居区域向四个方向扩展改造工作,直到无法再继续改造或者所有可改造区域都已改造成宜居区域。
Q1. YES值表示宜居区吗?上下左右的动作是什么值发起的?
YES 值表示宜居区,上下左右的动作表示人类站在一个宜居区域,然后可以选择向上、下、左、右四个方向之一扩展改造工作,将相邻的可改造区域改造成宜居区域。这些动作帮助人类逐步改造整个区域,直到所有可改造区域都变成宜居区域,或者无法再继续改造为止。
Q2.什么是太阳日天数? 有几个yes,就表示一天有几个人,各发起一次上/下/左/右四个方向之一的改造工作吗?
太阳日天数是指完成火星上的大气改造所需的时间,这个时间单位可以理解为一天。在这个问题中,每个YES表示一个宜居区,但不代表一定有一个人,而是表示这个区域已经改造成适合人类居住的状态。然后,每个人可以站在一个宜居区,朝上、下、左、右四个方向之一移动,将相邻的可改造区域改造成宜居区域。所以,如果有多个宜居区域,那么每个宜居区域上都可以有一个人,他们可以同时发起上、下、左、右四个方向之一的改造工作,但每个人只能改造一个方向的区域。
太阳日天数表示在每个太阳日(一天)内,人们可以进行一系列改造操作,然后计算需要多少天才能将所有的可改造区域变成宜居区域。
3.代码
代码思路:
- 遍历整个网格,找到所有可改造区(NO)。
- 对于每个可改造区,检查其上下左右相邻的格子是否为宜居区(YES),如果是,则将该格子标记为宜居区。
- 记录需要改造的格子数量,如果可改造区全部变成宜居区,则返回改造的太阳日天数,否则返回-1。
'''
1.livable_days函数接收一个二维列表grid作为输入,表示待改造区域的网格数据。
2.directions变量存储了上下左右四个方向的偏移量。
3.visited变量用于记录每个格子是否已经访问过,避免重复访问。
4.dfs函数用于深度优先搜索,将可改造区周围的宜居区标记为宜居区。
5.遍历整个网格,找到所有可改造区,然后使用dfs函数进行改造。
6.如果所有可改造区都变成了宜居区,则返回改造的太阳日天数,否则返回-1。
'''
def livable_days(grid):rows, cols = len(grid), len(grid[0])directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]visited = [[False for _ in range(cols)] for _ in range(rows)]days = 0def dfs(x, y):nonlocal days# 检查当前格子是否在网格范围内、是否已经访问过以及是否被标记为不可通行('NA')# 如果是任何一种情况,就返回,否则标记当前格子为已访问。if not (0 <= x < rows and 0 <= y < cols) or visited[x][y] or grid[x][y] == 'NA':returnvisited[x][y] = True# 在四个方向上尝试移动,如果邻近格子是可通行的('NO'),# 则递归调用dfs函数来继续探索这个格子的连通区域。for dx, dy in directions:nx, ny = x + dx, y + dyif 0 <= nx < rows and 0 <= ny < cols and grid[nx][ny] == 'NO':dfs(nx, ny)# 在两个嵌套的循环中,遍历整个网格。如果发现一个未访问过的不可通行格子('NO'),# 就增加days计数并启动DFS来探索与该格子相连的所有不可通行格子。for i in range(rows):for j in range(cols):if grid[i][j] == 'NO' and not visited[i][j]:days += 1dfs(i, j)# 如果网格中所有的格子都已经被标记为可通行('YES'),则返回已经过的天数days,# 否则返回-1,表示无法使整个网格变得全通行。return days if all(grid[i][j] == 'YES' for i in range(rows) for j in range(cols)) else -1'''
# 示例1
grid1 = [['YES', 'YES', 'NO'],['NO', 'NO', 'NO'],['YES', 'NO', 'NO']]print(livable_days(grid1)) # 输出:2# 示例2
grid2 = [['YES', 'NO', 'NO', 'NO'],['NO', 'NO', 'NO', 'NO'],['NO', 'NO', 'NO', 'NO'],['NO', 'NO', 'NO', 'NO']]
print(livable_days(grid2)) # 输出:6# 示例3
grid3 = [['NO', 'NA'],['NA', 'NA']]
print(livable_days(grid3)) # 输出:-1# 示例4
grid4 = [['YES', 'NO', 'NO', 'YES'],['NO', 'NO', 'YES', 'NO'],['NO', 'YES', 'NA', 'NA'],['YES', 'NO', 'NA', 'NO']]
print(livable_days(grid4)) # 输出:-1
'''