Python蓝桥杯ALGO-1001 跳马

题目描述如下

问题描述
  一个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))

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值