蓝桥杯刷题020——青蛙跳杯子(BFS)

2017省赛

题目描述

X 星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。

X 星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。

如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。

∗WWWBBB

其中,W 字母表示白色青蛙,B 表示黑色青蛙,∗ 表示空杯子。

X 星的青蛙很有些癖好,它们只做 3 个动作之一:

  1. 跳到相邻的空杯子里。

  2. 隔着 1 只其它的青蛙(随便什么颜色)跳到空杯子里。

  3. 隔着 2 只其它的青蛙(随便什么颜色)跳到空杯子里。

对于上图的局面,只要 1 步,就可跳成下图局面:

WWW∗BBB

本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面

输入描述

输入为 2 行,2 个串,表示初始局面和目标局面。我们约定,输入的串的长度不超过 15。

输出描述

输出要求为一个整数,表示至少需要多少步的青蛙跳。

输入输出样例

输入

*WWBB
WWBB*

输出

2

题目大意

给出一些青蛙的起始分布状态A,和青蛙经过跳跃后的最终状态B,求出最少的跳跃次数。

最少跳跃次数,类似最小步数问题,可用BFS求解

思路:
 

无论怎么跳,空杯子只有一个,而且青蛙只会跳到空杯子里去。
计算所有青蛙的跳跃情况太麻烦,不如直接让空杯子跳,和原问题等价。

合法的跳跃情况

  1. 相邻位置跳跃
  2. 间隔一个位置跳跃
  3. 间隔两个位置跳跃

skip: [1,-1,2,-2,3,-3],六种跳跃情况,所以有六个分支
正数表示空杯子向右“跳跃”
负数表示空杯子向左“跳跃”

从起始状态开始BFS,过程中记录从起始转移到每个状态需要的跳跃步数
搜索到目标状态,即可停止,输出步数
去重:用set()记录所有的中间状态,搜索过程中,对于已经在set()中出现过的状态,不进入队列

代码: 

from collections import deque
import sys
st = input()    # 起始状态
ed = input()    # 目标状态
all_st = set()  # 记录所有状态的集合
q = deque()

skip = [1, -1, 2, -2, 3, -3]        # 六种跳法

q.append([list(st), 0])             # 起点入队:状态和步数
all_st.add(st)                      # 加入起始状态
while len(q):        # 队列不为空时
    cst, cstep = q.popleft()        # 取出当前状态和步数
    for ne in skip:                 # 遍历所有的跳法
        lcst = cst.copy()           # 使用列表的深复制
        p = lcst.index('*')         # 找一下*的位置
        np = p + ne                 # 空杯的下一个位置
        if 0 <= np < len(cst):      # 只能在这个范围内跳
            lcst[p], lcst[np] = lcst[np], lcst[p]  # 交换空杯和青蛙的位置
            now_step = cstep + 1    # 步数+1
            new_st = ''.join(lcst)   # 将新状态转成字符串
            if new_st == ed:         # 如果新状态是目标状态
                print(now_step)      # 打印出当前步数
                sys.exit(0)          # 退出
            # 判重
            if new_st not in all_st: # 如果新状态不在集合里
                all_st.add(new_st)   # 加进去集合
                q.append([lcst, now_step])  # 加入新状态

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小叶pyか

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值