BFS算法之青蛙跳杯子(Python实现)

题目描述

X 星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X 星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。

∗WWWBBB

其中,W 字母表示白色青蛙,B 表示黑色青蛙,∗ 表示空杯子。
X 星的青蛙很有些癖好,它们只做 3 个动作之一:

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

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

WWW∗BBB

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

输入描述

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

输出描述

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

输入输出样例

示例

输入

*WWBB
WWBB*

输出

2

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

代码

from collections import deque

dirs = [-3 , -2 , -1 , 1 , 2 , 3]

def bfs(start , target) :
    q = deque([(start , 0)])
    # 创建一个空的集合visited,用于存储已访问的状态,避免重复访问。
    visited = set()
    # 将初始状态加入到visited集合中,表示已经访问过此状态。
    visited.add(start)
    while q :
        current , steps = q.popleft()
        if current == target :
            return steps
        empty_idx = current.index('*')
        for d in dirs :
            next_idx = empty_idx + d
            if 0 <= next_idx < len(current) :
                # 创建当前状态的一个副本new_state,并将其转换为列表,以便进行元素交换。
                new_state = list(current)
                new_state[empty_idx] , new_state[next_idx] = new_state[next_idx] , new_state[empty_idx]
                # 将列表new_state重新合并为字符串,使其可以添加到visited集合中。
                new_state = ''.join(new_state)
                if new_state not in visited :
                    visited.add(new_state)
                    q.append((new_state , steps + 1))
    return -1

if __name__ == "__main__" :
    start = input().strip()
    target = input().strip()
    print(bfs(start , target))

相关知识

1、join()函数

语法:  'sep'.join(seq)

参数说明
sep:分隔符。可以为空
seq:要连接的元素序列、字符串、元组、字典
上面的语法即:以sep作为分隔符,将seq所有的元素合并成一个新的字符串

返回值:返回一个以分隔符sep连接各个元素后生成的字符串

2、deque
deque 是Python标准库 collections 中的一个类,实现了两端都可以操作的队列,相当于双端队列,与Python的基本数据类型列表很相似。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

会有风

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

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

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

打赏作者

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

抵扣说明:

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

余额充值