广度优先算法
我的理解是在搜索时向一切可能进行的方向搜索,拿经典的走迷宫问题举例子,每次遇到十字路口,就分出三个分身把三个可能的方向都走一遍,这里采用一个数据结构队列,先进先出的保存路径,可以走的状态就保存一下,每次走之前先从队列里面取出来一个状态点,从这一点开始走。
Python实现
Python中已经实现了队列(queue)的结构,直接import就可以使用,然而queue在py2和py3中是有区别的,我在刷oj的时候遇到了这个问题。不过Python给用户提供了比较强大的数据结构列表:list,干脆直接用最基本的list结构来处理这个问题。
使用到的list方法
list.append(obj)
在list尾部添加元素objlist.pop([index=-1])
移除并返回列表中的某一项 默认为最后一项 移除第二项可以写作list.pop(1)
del
Python的删除关键字,移除第一项可以写作del list[0]
两个实例
最短路径
Pythontip 24一马当先1
下过象棋的人都知道,马只能走’日’字形(包括旋转90°的日),现在想象一
下,给你一个n行m列网格棋盘,
棋盘的左下角有一匹马,请你计算至少需要几步可以将它移动到棋盘的右上
角,若无法走到,则输出-1.
如n=1,m=2,则至少需要1步;若n=1,m=3,则输出-1。
这个题可以广度搜索,基本思路是每次向八个方向中没走过的方向都走一遍,可以证明重复走过某一点一定会比只经过这一点一次路径要长,建立一个used数组保存使用过的点,不走重复路。建立一个map数组记录距离。题目中没有设置陷阱蹩马腿,还算比较良心。ac代码如下:
# n = 1
# m = 3
map = [[100000000 for x in range(m + 1)] for y in range(n + 1)]
used = [[0 for x in range(m + 1)] for y in range(n + 1)]
map[0][0] = 0
dx = [1, -1, 1, -1, 2, -2, 2, -2]
dy = [2, -2, -2, 2, 1, -1, -1, 1] # 八个扩展方向
horses = []
horses.append([0, 0])
while (horses):
h = horses[0] # 取出第一项
del horses[0] # 删除第一项
if h[0] == n and h[1] == m: # 已达终点
break
for i in range(8): # 八个方向探索
nx = h[0] + dx[i]
ny = h[1] + dy[i]
if nx >= 0 and nx <= n and ny >= 0 and ny <= m and used[nx][ny] == 0:
map[nx][ny] = map[h[0]][h[1]] + 1 # 记录长度
used[nx][ny] = 1 # 已经使用
horses.append([nx, ny]) # 将该点保存在list中
if map[n][m] != 100000000:
print(map[n][m])
else:
print(-1)
最长路径
Pythontip 78 滑雪比赛2
我们把场地分为一个个的格子,给每个格子标定一个整数,代表这个格子所代表的地面的海拔高度。
比赛的参赛者可以从任意一个格子开始,但只能向相邻的四个格子移动,并且目地格子的高度必须
小于现在所在格子的高度。我们假设从一个格子滑行到另一个格子所用的时间为1个单位时间。
现在告诉你滑雪场的大小为n*m, 并给你一个n行m列的整数二维列表H,表示每个格子的海拔高度。
请你计算出在这个场地上最长能滑行多少时间。
如:
n = 4
m = 4
H= [
[1, 2, 3, 4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]
]
则输出 6.
这里显然是从最高点出发,在最低点结束,但是第一个到达最低点的是路径最短的,这里可以换个思路,在list中的点除了x,y坐标外再加上一个新变量t,这个新变量表示了路程或时间,每次都在list中取前端,直到list中没有元素,那么最后一个取出的元素是在list中待的时间最长的,那么它一定表示最长路径。
ac代码如下:
# ~ n = 4
# ~ m = 4
# ~ H= [
# ~ [1, 2, 3, 4],
# ~ [5,6,7,8],
# ~ [9,10,11,12],
# ~ [13,14,15,16]
# ~ ]
maxx = 0
maxy = 0
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0] # 四个可能的方向
for i in range(n): # 寻找最高点
for j in range(m):
if H[i][j] > H[maxx][maxy]:
maxx = i
maxy = j
temp = [maxx, maxy, 0] # 第一个元素 起点坐标加初始路程
que = []
que.append(temp)
while (que):
temp = que.pop(0) # 取第一项
for i in range(4): # 四方向搜索
nx = temp[0] + dx[i]
ny = temp[1] + dy[i]
if n > nx >= 0 and m > ny >= 0 and H[nx][ny] < H[temp[0]][temp[1]]:
t = [nx, ny, temp[2] + 1] # 新位置的信息
que.append(t) # 保存在list中
print(temp[2]) # 输出最后元素的路程