"广度优先搜索"是一种通过逐层遍历所有访问对象,从而找到通过最短节点数到达目标的算法。
例题:1. 2018年第九届真题全球变暖
题目:
参考博客:(165条消息) 蓝桥杯精选赛题算法系列——全球变暖——BFS_wzyannn的博客-CSDN博客
这个博主写的很好,最开始也明白广度优先算法的具体流程是怎样的,但是对这个题采用广度优先方法来寻找连通块就不是很理解,但是自己在代码中加上中文的解释,把整个代码跑一遍,打印出整道题用广度优先算法解题的流程也就明白了。
跟着代码解题的流程再来看这道题,每个bfs都是求这一个连通块的所有点坐标,然后判断这些点中的哪个点周围全是陆地,符合条件的话就标记一下。最后看一共标记了几次,答案就是几。
下面是我加上中文解释后的代码:
def bfs(x,y):
d = [(0,1),(0,-1),(1,0),(-1,0)]
q = [(x,y)] #用list实现队列
print('现在队列里面有点')
print(q)
vis[x][y]=1
global flag
while q:
t=q.pop(0)
print('取出一个点')
print(t)
tx,ty = t[0],t[1]
if mp[tx][ty+1]=='#' and mp[tx][ty-1]=='#' and \
mp[tx+1][ty]=='#' and mp[tx-1][ty]=='#':
flag = 1
print('经判断这个点的四周全是陆地,所以标记flag为1')
for i in range(4):
nx = tx+d[i][0]
ny = ty+d[i][1]
print('遍历到这个点')
print((nx,ny))
if vis[nx][ny]==0 and mp[nx][ny]=="#":
q.append((nx,ny))
print('上面这个点没有访问过并且是陆地,把他放到队列里面')
vis[nx][ny]=1
n = int(input())
mp =[]
for i in range(n):
mp.append(list(input()))
vis = []
for i in range(n):
vis.append([0]*n)
ans = 0
for i in range(n):
for j in range(n):
if vis[i][j]==0 and mp[i][j]=="#":
flag = 0
print('从下面这个点开始广度优先遍历')
print((i,j))
bfs(i,j)
if flag == 0:
ans+=1
print(ans)
注意:浅拷贝和深拷贝的区别!!!
我在看完博主写的博客以后,自己编写了一遍。但是写的不对,后来检查了好久才发现是因为:
我创建二维全零列表vis的时候是用的[[0]*n]*n。我看生成的列表和for i in range(n):
vis.append([0]*n)生成的列表是一样的,所以就以为这俩一样!!
但是这俩是有区别的。用[[0]*n]*n生成的列表是浅复制,每一行的改变都会该表其他行!
这俩的区别看:(159条消息) 如何创建二维数组 以及 python中[0 ]* n与[0 for _ in range(n)]的区别与联系_剑圣土豆的博客-CSDN博客