n行m列网络棋盘,棋子只能走日字形,从左下角至少需要几步可以移动到棋盘的右上角?
题目来源:http://www.pythontip.com/codi...
问题描述:
下过象棋的人都知道,马只能走'日'字形(包括旋转90°的日),现在想象一下,给你一个n行m列网格棋盘,棋盘的左下角有一匹马,请你计算至少需要几步可以将它移动到棋盘的右上角,若无法走到,则输出-1.如n=1,m=2,则至少需要1步;若n=1,m=3,则输出-1。
思路:
马走日,从某一点开始走,一共有8种走法:
题目要求从左下走到右上,那么能用上的就是坐标轴第一和第四象限的4种走法,需要根据实际位置判断马下一步怎么走,而且走的总步数最少,需要使用广度优先遍历从某一步到下一步的所有走的路径,还需要记录步长,考虑最短路径。 算法能力比较差,代码的具体编写没写出来。
这是关于这道题的解题报告:http://www.pythontip.com/codi...
里面的思路有给广度优先加剪枝的,还有用向量的,但是有4层for循环复杂度太高。
希望可以帮忙分析下这道题,谢谢大家。
回答:
既然是计算最小步数,确实是可以使用广度优先的算法来计算。如果你不太了解广度优先算法具体是什么,建议先google了解算法。
- 首先我们需要一个队列
Q
存储待访问的点,一个map记录访问过的点visited[maxL][maxH]
,起始点为vs=[0,0,0]
0,1两点记录坐标,2点记录index步长, 结束点为vd=[n,m], Q.append(vs), 把起始点丢进队列里。 - 马走日,创建两个list列出x和y可走的方向
dx=[1,1,2,2,-1,-1,-2,-2], dy=[2,-2,1,-1,2,-2,1,-1]
while Q:
只要有未访问的点,就执行循环。vn=Q.pop(0)
, 取出队列第一个点并抛掉,if [vn[0],vn[1]] == vd: return vn[2]
如果发现此点就是想要的点,直接返回index步长,得到结果。- 如果不是结果,就寻找与此节点相邻的未访问的点:
for (x,y) in zip(dx,dy): #我这边用了zip打包dx,dy。也可以直接就写成二维 vnx=vn[0]+x # for循环出所有可能的下一个节点
vny=vn[1]+y
index=vn[2]+1 # 步长为vn的步长+1,就是上一个节点的index+1
if 0<=vnx<=n and 0<=vny<=m and visited[vnx][vny] != 1: # 判断是否超出边界,是否已经访问过
visited[vnx][vny] = 1 # 标记节点已访问,并插入队列Q
Q.append([vnx, vny, index])
- 最后检索完毕没有找到结果,
return -1
方法仅供参考,虽然过了你那个题目的测试。
以上是 n行m列网络棋盘,棋子只能走日字形,从左下角至少需要几步可以移动到棋盘的右上角? 的全部内容, 来源链接: utcz.com/a/158034.html