题目描述如下
问题描述
一个8×8的棋盘上有一个马初始位置为(a,b),他想跳到(c,d),问是否可以?如果可以,最少要跳几步?
输入格式
一行四个数字a,b,c,d。
输出格式
如果跳不到,输出-1;否则输出最少跳到的步数。
样例输入
1 1 2 3
样例输出
1
数据规模和约定
0<a,b,c,d≤8且都是整数。
作为小白,拿到这个题还是有点思路的,可能是年龄大了,反应太慢,这个题目写了好久
首先题目约束了棋盘大小8x8 其次就是状态变化约束条件是按照象棋中的🐎走。。。。。。要寻找最短的路长。。。。。第一反应想到广度优先搜索。。。。。。。
BFS遍历到的第一次终点所经历过的路长就是我们需要求的解
这个题目已经筛除了很多很多干扰条件,比如这个BFS搜索空间一定是联通的,我们仅需一次BFS即可
那么就有点类似于树的层次遍历法了。
简单思路如下,三句话:
1.首先,让起点进队列
2.以队列不为空为约束条件,开始while循环
3.队头出队列,队头顶点的邻居入队列
注意:需要使用visit标记当前顶点是否访问
def BFS(source,target,visit):
queue.append(source)
visit[source[0]][source[1]]=True
epoch=0
while len(queue)!=0:
# 出队一个顶点
tmp=queue.popleft()
neighbors=get_neighbors(tmp)
#遍历刚刚出队列顶点的所有邻居
for neighbor in neighbors:
#如果遍历到target 直接返回第几层
if neighbor[0]==target[0] and neighbor[1]==target[1]:
return tmp[2]+1
#否则,继续遍历没遍历的顶点
elif not visit[neighbor[0]][neighbor[1]]:
#这里每个顶点包含三列特征,分别是(x,y,L) L表示当前在第几层,因此,一个顶点tmp的邻居neighbor的层数应该是tmp的层数加一
#这也是这个算法的难点所在
neighbor[2]=tmp[2]+1
#遍历过了要更新visit,并将顶点加入队列
queue.append(neighbor)
visit[neighbor[0]][neighbor[1]]=True
#
有了上面的BFS代码,,本题中如何获得某一节点的邻居?
代码如下,我觉得都看得懂,就不解释了
def get_neighbors(source):
step=[-1,1,2,-2]
res=[]
x,y=source[0],source[1]
for i in step:
deta_x=x+i
if deta_x>8 or deta_x<=0:
continue
for j in step:
if abs(i)==abs(j):
continue
deta_y=y+j
if deta_y>8 or deta_y<=0:
continue
res.append([deta_x,deta_y,0])
return res
最终代码如下:
import collections
#获取邻居
def get_neighbors(source):
step=[-1,1,2,-2]
res=[]
x,y=source[0],source[1]
for i in step:
deta_x=x+i
if deta_x>8 or deta_x<=0:
continue
for j in step:
if abs(i)==abs(j):
continue
deta_y=y+j
if deta_y>8 or deta_y<=0:
continue
res.append([deta_x,deta_y,0])
return res
def BFS(source,target,visit):
queue.append(source)
visit[source[0]][source[1]]=True
epoch=0
while len(queue)!=0:
# 出队一个顶点
tmp=queue.popleft()
neighbors=get_neighbors(tmp)
#遍历刚刚出队列顶点的所有邻居
for neighbor in neighbors:
#没访问过的顶点才遍历
if neighbor[0]==target[0] and neighbor[1]==target[1]:
return tmp[2]+1
elif not visit[neighbor[0]][neighbor[1]]:
neighbor[2]=tmp[2]+1
queue.append(neighbor)
visit[neighbor[0]][neighbor[1]]=True
#
a,b,c,d=map(int,input().split())
# a,b,c,d=1,1,8,8
#特殊情况要注意,不然不能满分
if a==c and b==d:
print(0)
else:
queue=collections.deque()
visit=[[False for i in range(9)] for j in range(9)]
source=[a,b,0]
target=[c,d]
print(BFS(source,target,visit))