Crossin的编程教室
标题:
【求助】一马当先
[打印本页]
作者:
fangweiren
时间:
2016-2-17 10:37
标题:
【求助】一马当先
下过象棋的人都知道,马只能走'日'字形(包括旋转90°的日),现在想象一下,给你一个n行m列网格棋盘,棋盘的左下角有一匹马,请你计算至少需要几步可以将它移动到棋盘的右上角,若无法走到,则输出-1.如n=1,m=2,则至少需要1步;若n=1,m=3,则输出-1。
@Cross先生,没有一点思路,求问怎么解
作者:
crossin先生
时间:
2016-2-17 11:54
1.把当前状态可以眺到位置记录在一个list1中,记下步数
2.然后再计算list1的所有能跳到的位置,记录在list2,记下步数,更新list1为list2
3.重复2,知道list2包含终点(成功,输出步数),或list2等于list1(失败,输出-1)
作者:
小燕smile
时间:
2016-4-13 16:00
我这边给出一个大致的解法,你看看,希望能对你有所启发:
def check(x1,y1,x2,y2): #检查是否到达指定的点
if x1==x2 and y1==y2:
return True
return False
def find_way(x1,y1,x2,y2):
'''由于假设是从左下角开始走,所以我只用了马的四种走法(实际有八种),
我假设马只能向右侧走(因为要去右上角),并且优先采用了(1,2)和(2,1)这种走法'''
global step
if check(x1+1,y1+2,x2,y2):
step+=1
chessboard[x1][y1]=step
return step
elif x1+1<x2 and y1+2<y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1+1,y1+2,x2,y2)
if check(x1+2,y1+1,x2,y2):
step+=1
chessboard[x1][y1]=step
return step
elif x1+2<x2 and y1+1<y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1+2,y1+1,x2,y2)
if check(x1+2,y1-1,x2,y2):
step+=1
chessboard[x1][y1]=step
return step
elif x1+2<x2 and y1-1<y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1+2,y1-1,x2,y2)
if check(x1+1,y1-2,x2,y2):
step+=1
chessboard[x1][y1]=step
return step
elif x1+1<x2 and y1-2<y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1+1,y1-2,x2,y2)
return -1
复制代码
作者:
小燕smile
时间:
2016-4-13 16:03
使用py3.4编写,基于win7平台下面的pycharm4.5测试,下面是编写的测试用例:
cols=8
rows=8
chessboard=[[0 for col in range(cols)] for row in range(rows)]
step=0
print(find_way(0,0,7,7))
for i in range(rows):
for j in range(cols):
print(chessboard[i][j],'',end='',)
print('\t')
复制代码
注意:我的坐标系是从(0,0)开始的,故(7,7)在实际坐标中为(6,6)
测试结果:
-1
1 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0
0 0 0 0 3 0 0 0
0 0 0 0 0 0 4 0
0 0 0 0 0 0 0 0
0 0 0 0 0 5 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
作者:
小燕smile
时间:
2016-4-13 16:13
cols=8
rows=8
chessboard=[[0 for col in range(cols)] for row in range(rows)]
step=0
复制代码
这四行应该写到实际代码中,粘错了~~~
另外几点说明:
以上代码存在很多缺陷,有很大的改进空间,例如:
1.马在某一点最多存在八种走法,需要根据实际的位置判断马实际满足几种下一步走法,而本算法只写了四种;
2.if语句的顺序影响了下一步走法尝试的顺序,故本算法只得出了其中一种走法,没有遍历出所有的走法来;
3.其他尚未写出的缺陷
希望看到该代码的大神能够完善出一个能求的在任一点寻路到另外一点的最短路径算法,互相学习!
由于没有怎么学习过算法,全是自己瞎捉摸的,希望能够抛砖引玉!
作者:
crossin先生
时间:
2016-4-13 21:15
小燕smile 发表于 2016-4-13 16:13
这四行应该写到实际代码中,粘错了~~~
另外几点说明:
以上代码存在很多缺陷,有很大的改进空间,例如:
赞。欢迎大家多交流代码
作者:
小燕smile
时间:
2016-4-13 21:30
晚上对上面代码中不完善的地方做了进一步修正,修正如下:
def check(x1,y1,x2,y2): #检查是否到达指定的点
if x1==x2 and y1==y2:
return True
return False
def find_way(x1,y1,x2,y2):
'''由于假设是从左下角开始走,所以我只用了马的四种走法(实际有八种),
我假设马只能向右侧走(因为要去右上角),并且优先采用了(1,2)和(2,1)这种走法'''
global step
if check(x1+1,y1+2,x2,y2):
step+=1
chessboard[x1][y1]=step
step+=1
chessboard[x1+1][y1+2]=step
return step
elif x1+1<x2 and y1+2<y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1+1,y1+2,x2,y2)
if check(x1+2,y1+1,x2,y2):
step+=1
chessboard[x1][y1]=step
step+=1
chessboard[x1+2][y1+1]=step
return step
elif x1+2<x2 and y1+1<y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1+2,y1+1,x2,y2)
if check(x1+2,y1-1,x2,y2):
step+=1
chessboard[x1][y1]=step
step+=1
chessboard[x1+2][y1-1]=step
return step
elif x1+2<x2 and y1-1<y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1+2,y1-1,x2,y2)
if check(x1+1,y1-2,x2,y2):
step+=1
chessboard[x1][y1]=step
step+=1
chessboard[x1+1][y1-2]=step
return step
elif x1+1<x2 and y1-2<y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1+1,y1-2,x2,y2)
#另外四种走法:
if check(x1-2, y1+1, x2, y2):
step += 1
chessboard[x1][y1] = step
return step
elif 0 < x1-2 < x2 and y1+1 < y2:
step += 1
chessboard[x1][y1] = step
return find_way(x1-2, y1+1, x2, y2)
if check(x1-1, y1+2, x2, y2):
step += 1
chessboard[x1][y1] = step
return step
elif 0 < x1-1 < x2 and y1+2 < y2:
step += 1
chessboard[x1][y1] = step
return find_way(x1-1, y1+2, x2, y2)
if check(x1-1,y1-2,x2,y2):
step+=1
chessboard[x1][y1]=step
return step
elif 0 < x1-1 < x2 and 0< y1-2 < y2:
step+=1
chessboard[x1][y1]=step
return find_way(x1-1,y1-2,x2,y2)
if check(x1-2, y1-1, x2, y2):
step += 1
chessboard[x1][y1]=step
return step
elif 0 < x1-2 < x2 and 0 < y1-1 < y2:
step += 1
chessboard[x1][y1] = step
return find_way(x1-2, y1-1, x2, y2)
return -1
cols=9
rows=9
chessboard = [[0 for col in range(cols)]for row in range(rows) ]
step=0
print(find_way(0,0,8,8)-1)
chessboard.reverse()
for i in range(cols):
for j in range(rows):
print (chessboard[i][j],'',end='',)
print('\t')
复制代码
修正后的代码比之前稍微好些了,只是有时会存在递归太深的问题,暂时没想到具体原因
作者:
小燕smile
时间:
2016-4-13 21:33
修正后的实际效果如下:
6
0 0 0 0 0 0 0 0 7
0 0 0 0 0 0 6 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 5 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 4 0 0
0 0 0 0 3 0 0 0 0
0 0 2 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
修正后,将(0,0)点移到左下角,并且调整了之前代码在棋盘上不会显示最后一步的问题,并且在代码中添加了另外四种走法(发现添加后在某些情况下会出现递归过深的问题,暂时未解决)
欢迎光临 Crossin的编程教室 (https://bbs.crossincode.com/)
Powered by Discuz! X2.5