网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透,在此情况下需要计算某个位置的网络信号值。注意:网络信号可以绕过阻隔物
array[m][n]
的二维数组代表网格地图,array[i][j] = 0
代表 i
行 j
列是空旷位置;array[i][j] = x
( x
为正整数)代表 i
行 j
列是信号源,信号强度是 x
;array[i][j] = -1
代表 i
行 j
列是阻隔物.1
个,阻隔物可能有 0
个或 多
个1
输入为三行:
第一行为 m
、n
,代表输入是一个 m × n
的数组。
第二行是一串 m × n
个用空格分隔的整数。每连续 n
个数代表一行,再往后 n
个代表下一行,以此类推。 对应的值代表对应的网格是空矿位置,还是信号源,还是阻隔物。
第三行是 i
、j
,代表需要计算 array[i][j]
的网络信号值。注意:此处i
和j
均从 0
开始,即第一行 i
为 0
例如
6 5
0 0 0 -1 0 0 0 0 0 0 0 0 -1 4 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0
1 4
代表如下地图
需要输出第 1
行第 4
列的网络信号值,如下图,值为 2
输出对应位置的网络信号值,如果网络信号未覆盖到,也输出 0。
一个网格如果可以途径不同的传播衰减路径传达,取较大的值作为其信号值。
6 5
0 0 0 -1 0 0 0 0 0 0 0 0 -1 4 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0
1 4
2
6 5
0 0 0 -1 0 0 0 0 0 0 0 0 -1 4 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0
2 1
0
输出-1
。右下角的区域,被周边三个死亡区挡住,无法实现改造。
m
不一定等于n
,m < 100
,n < 100
,网络信号小于 1000
。1
个,阻隔物可能有 0
个或多个。m
,n
与第二行的数组是合法的,无需处理数量对不上的异常情况。注意,本题和LC994. 腐烂的橘子几乎完全一致,属于计算BFS层数的问题,而且只有一个信号源,所以使用常规的单源BFS方法即可完成。
要注意以下几点:
m*n
的一维数组,需要转换成我们常用的grid
二维矩阵。grid
上进行元素修改,最终输出要求的点(target_x, target_y)
的强度值grid[target_x][target_y]
即可。grid
进行修改,如果某个点的强度已经从0
修改为其他值,说明已经进入过,故无需重复使用checkList
进行检查。intensity
不断-1
来判断,无需从level = 0
开始递增。# 题目:2023Q1A-计算网络信号
# 分值:200
# 作者:许老师-闭着眼睛学数理化
# 算法:多源BFS
# 代码看不懂的地方,请直接在群上提问
from collections import deque
# 搜索的四个方向
D = [(0,1), (1,0), (-1,0), (0,-1)]
m, n = map(int, input().split())
lst = list(map(int, input().split()))
target_x, target_y = map(int, input().split())
# 需要把lst转化为常用的grid二维数组
grid = list()
for i in range(0, m*n, n):
# lst中的每n个元素作为一行,存入grid中
grid.append(lst[i:i+n])
q = deque()
# 双重循环遍历grid,寻找信号源
for i in range(m):
for j in range(n):
# 0表示空地,-1表示阻碍,故grid[i][j]大于0时,点(i,j)是信号源
if grid[i][j] > 0:
# 将信号源存入队列q中,作为BFS的起始位置
q.append((i, j))
# 获得信号源的强度intensity
intensity = grid[i][j]
# 由于有且只有一个信号源,所以找到信号源后直接退出循环
break
# 注意,本题可以直接在grid数组上进行修改,故无需设置checkList检查数组
# 另外,搜索层数可以根据intensity递减
while len(q) > 0:
# 本次搜索,强度-1
intensity -= 1
# 如果强度降为0,无需进行搜索,直接退出循环
if intensity == 0:
break
# 获得当前队列长度,为本层BFS需要出队的节点数
qSize = len(q)
for _ in range(qSize):
# 弹出当前队头元素点(x, y)
x, y = q.popleft()
# 遍历点(x, y)的近邻点
for dx, dy in D:
nx, ny = x+dx, y+dy
# (nx, ny)需要满足:
# 1. 不越界
# 2. 在grid中为0
if (0 <= nx < m and 0 <= ny < n and grid[nx][ny] == 0):
# 直接将grid[nx][ny]修改为强度intensity
# 这一步替代了checkList
grid[nx][ny] = intensity
# 并且将点(nx, ny)加入队列中继续进行搜索
q.append((nx, ny))
# 最后输出grid中点(target_x, target_y)的值即可
print(grid[target_x][target_y])
时间复杂度:O(MN)
。需要遍历整个grid
二维数组。
空间复杂度:O(1)
。无需checkList
,不考虑grid
二维数组所占空间,仅需若干常数变量。
华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
可查看链接 OD算法冲刺训练课程表 & OD真题汇总(持续更新)
绿色聊天软件戳 od1336
了解更多