【蓝桥杯】43692.青蛙跳杯子

news2025/3/4 12:32:57

题目描述

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

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

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

∗ W W W B B B ∗WWWBBB WWWBBB

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

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

跳到相邻的空杯子里。

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

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

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

W W W ∗ B B B WWW∗BBB WWWBBB

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

输入描述

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

输出描述

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

输入输出样例

示例
输入

※WWBB
WWBB※

输出

2

解题思路

先来看看 ∗ W W W B B B ∗WWWBBB WWWBBB 怎么变成 W W W ∗ B B B WWW∗BBB WWWBBB
很简单,第三个 W 的青蛙向左跳了2格,占了 ∗ ∗ 的位置,而跳走后,原来的位置变为 ∗ ∗
在这里插入图片描述
再看看 ∗ W W B B *WWBB WWBB 怎么变为 W W B B ∗ WWBB* WWBB
至少需要两步: ∗ W W B B *WWBB WWBB W W ∗ B B WW*BB WWBB W W B B ∗ WWBB* WWBB

对于已知初始状态和结束状态的题目,简单粗暴的解题思路无非两种,一种枚举,一种遍历,把所有的可能性都试一遍,而找出其中 路径最短 / 步骤最少 的,无疑要使用遍历算法,那么优先考虑 广度优先BFS深度优先DFS

假设起始局面为 ∗ W W B B *WWBB WWBB,目标局面为 W W B B ∗ WWBB* WWBB

  1. 初始时,队列 Q = [[‘ ∗ W W B B *WWBB WWBB’, 0]],集合 aset = {‘ ∗ W W B B *WWBB WWBB’}。
  2. 从队列取出 [‘ ∗ W W B B *WWBB WWBB’, 0],对其应用各种移动方式:
      当移动方式为 1 时,得到新局面 W ∗ W B B W*WBB WWBB,步数变为 1。检查发现 W ∗ W B B W*WBB WWBB 不在 aset 中,将其加入 aset 并把 [‘ W ∗ W B B W*WBB WWBB’, 1] 加入队列 Q。
      类似地,依次应用其他移动方式生成新局面并处理。
  3. 继续从队列中取出元素进行探索,直到找到目标局面 W W B B ∗ WWBB* WWBB,此时输出的步数即为从起始局面到目标局面的最少步数。

  通过这种逐层扩展搜索空间的方式,使用 广度优先搜索BFS 能够保证第一次找到目标状态时所经过的路径是最短的。

算法步骤

  1. 读取用户输入的初始局面和目标局面。
  2. 定义青蛙可能的移动方式。
  3. 使用集合 aset 记录已经访问过的局面,避免重复搜索。
  4. 初始化队列 Q,将初始局面和步数 0 加入队列。
  5. 不断从队列中取出元素,尝试所有可能的移动方式,得到新的局面。
  6. 如果新的局面等于目标局面,输出步数并结束搜索。
  7. 如果新的局面未被访问过,将其加入已访问集合和队列,继续搜索。

代码展示

感谢 @朱恒彤 同学提供的代码。

import os
import sys

# 从用户输入中读取初始局面和目标局面,start 是起始状态,end 是目标状态
start = input()
end = input()

# 定义青蛙可能的移动方式
# 这是一个列表,表示在字符串中可以移动的位数(向右或向左),
# 其中正数表示向右移动,负数表示向左移动。例如,1 表示向右移动 1 格,-2 表示向左移动 2 格
move = [1, -1, 2, -2, 3, -3]

# aset 是一个集合,集合的特点是元素具有唯一性,用于记录已经访问过的状态,以避免重复访问。
# 初始时将起始状态加入集合
aset = {start}

# 定义广度优先搜索函数
def bfs():
    # 初始化队列,队列中的每个元素是一个列表,包含当前局面和到达该局面所需的步数
    # 初始时队列中只有一个元素,即起始状态和对应的步数 0,说明步数是从 0 开始的
    Q = [[start, 0]]

    # 当队列不为空时,继续搜索
    while Q:
        # 从队列中取出队首元素
        # 运用了 while Q 循环。只要 Q 不为空,就会从队列中取出一个 old
        # old 是一个列表,old[0] 是当前局面,old[1] 是到达该局面所需的步数
        old = Q.pop(0)

        # 遍历所有可能的移动方式
        for i in move:
            # 将当前局面的字符串转换为字符列表,因为字符串是不可变类型,而列表是可变类型,方便进行字符交换操作
            a = list(old[0])

            # 获取到达当前局面所需的步数
            b = old[1]

            # 找到空位(用 '*' 表示)在字符列表中的索引
            c = a.index('*')

            # 计算空位移动后的新索引
            d = c + i

            # 检查新索引是否在合法范围内
            if 0 <= d < len(start):
                # 交换空位和新索引位置的字符
                a[c] = a[d]
                # 将新的字符位置的值转移到 '*' 的位置,把原来 '*' 的位置设置为新的字符
                a[d] = '*'

                # 将字符列表转换回字符串,重新形成新的状态字符,得到新的局面
                e = ''.join(a)

                # 步数加 1
                b += 1

                # 如果新的局面等于目标局面,输出当前步数并结束搜索
                if e == end:
                    print(b)
                    return

                # 如果新的局面未被访问过,将其加入已访问集合aset,表示为已访问,并加入队列Q,,表示加入新的局面和对应的步数,然后继续搜索
                if e not in aset:
                    aset.add(e)
                    Q.append([e, b])

# 调用广度优先搜索函数开始搜索
bfs()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2283953.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Dialog屏幕开发] 屏幕绘制(下拉菜单)

阅读该篇文章之前&#xff0c;可先阅读下述资料 [Dialog屏幕开发] Table Control 列数据操作https://blog.csdn.net/Hudas/article/details/145343731?spm1001.2014.3001.5501上篇文章我们的屏幕已实现了如下功能 我们已经设置了按钮对Table Control 列的数据进行了操作 接下…

AIGC视频生成模型:慕尼黑大学、NVIDIA等的Video LDMs模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍慕尼黑大学携手 NVIDIA 等共同推出视频生成模型 Video LDMs。NVIDIA 在 AI 领域的卓越成就家喻户晓&#xff0c;而慕尼黑大学同样不容小觑&#xff0c;…

JVM常见知识点

在《深入理解Java虚拟机》一书中&#xff0c;介绍了JVM的相关特性。 1、JVM的内存区域划分 在真实的操作系统中&#xff0c;对于地址空间进行了分区域的设计&#xff0c;由于JVM是仿照真实的机器进行设计的&#xff0c;那么也进行了分区域的设计。核心区域有四个&#xff0c;…

类和对象(4)——多态:方法重写与动态绑定、向上转型和向下转型、多态的实现条件

目录 1. 向上转型和向下转型 1.1 向上转型 1.2 向下转型 1.3 instanceof关键字 2. 重写&#xff08;overidde&#xff09; 2.1 方法重写的规则 2.1.1 基础规则 2.1.2 深层规则 2.2 三种不能重写的方法 final修饰 private修饰 static修饰 3. 动态绑定 3.1 动态绑…

系统思考—问题分析

很多中小企业都在面对转型的难题&#xff1a;市场变化快&#xff0c;资源有限&#xff0c;团队协作不畅……这些问题似乎总是困扰着我们。就像最近和一位企业主交流时&#xff0c;他提到&#xff1a;“我们团队每天都很忙&#xff0c;但效率始终没见提升&#xff0c;感觉像是在…

Midscene.js:重新定义UI自动化的新时代工具

前言 Midscene.js 是一个创新的、面向开发者的 UI 自动化解决方案&#xff0c;并通过人工智能技术简化自动化脚本的编写与维护。 它提供了三种核心方法——交互&#xff08;.ai, .aiAction&#xff09;、提取&#xff08;.aiQuery&#xff09;和断言&#xff08;.aiAssert&am…

go单元测试和基准测试

1、单元测试和基准测试 单元测试和基准测试代码开发中的重要环节&#xff0c;良好的单元测试和基准测试&#xff0c;能提升开发质量&#xff0c;对整体开发有非常重要的重要&#xff0c;下面介绍单元测试和基准测试的写法。 2、单元测试和基准测试写法 以排序基本排序算法&a…

Nuxt:利用public-ip这个npm包来获取公网IP

目录 一、安装public-ip包1.在Vue组件中使用2.在Nuxt.js插件中使用public-ip 一、安装public-ip包 npm install public-ip1.在Vue组件中使用 你可以在Nuxt.js的任意组件或者插件中使用public-ip来获取公网IP。下面是在一个Vue组件中如何使用它的例子&#xff1a; <template…

day7手机拍照装备

对焦对不上&#xff1a;1、光太暗&#xff1b;2、离太近&#xff1b;3、颜色太单一没有区分点 滤镜可以后期P 渐变灰滤镜&#xff1a;均衡色彩&#xff0c;暗的地方亮一些&#xff0c;亮的地方暗一些 中灰滤镜&#xff1a;减少光差 手机支架&#xff1a;最基本70cm即可 手…

LLM - 大模型 ScallingLaws 的指导模型设计与实验环境(PLM) 教程(4)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145323420 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 Scalin…

【Linux网络编程】传输层协议

目录 一&#xff0c;传输层的介绍 二&#xff0c;UDP协议 2-1&#xff0c;UDP的特点 2-2&#xff0c;UDP协议端格式 三&#xff0c;TCP协议 3-1&#xff0c;TCP报文格式 3-2&#xff0c;TCP三次握手 3-3&#xff0c;TCP四次挥手 3-4&#xff0c;滑动窗口 3-5&#xf…

FreeRtos的使用教程

定义&#xff1a; RTOS实时操作系统, (Real Time Operating System), 指的是当外界事件发生时, 能够有够快的响应速度,调度一切可利用的资源, 控制实时任务协调一致的运行。 特点&#xff1a; 支持多任务管理&#xff0c; 处理多个事件&#xff0c; 实现更复杂的逻辑。 与计算…

基于Ubuntu交叉编译ZLMediaKit

一、确保基于虚拟机VMVare的Ubuntu能正常上网 1、设置WIFI硬件无线网卡上网 菜单栏的“编辑”->选择“虚拟网络编辑器”&#xff0c;在弹出的窗口中&#xff0c;点击桥接模式的VMnet0&#xff0c;然后在下方选择“桥接模式”&#xff0c;网卡下拉栏&#xff0c;选择你目前…

【PyTorch][chapter 29][李宏毅深度学习]Fine-tuning LLM

参考&#xff1a; https://www.youtube.com/watch?veC6Hd1hFvos 目录&#xff1a; 什么是 Fine-tune 为什么需要Fine-tuning 如何进行Fine-tune Fine-tuning- Supervised Fine-tuning 流程 Fine-tuning参数训练的常用方案 LORA 简介 示例代码 一 什么是 Fine-tune …

数字图像处理:实验七

uu们&#xff01;这是我们目前数字图像系列的最后一张&#xff0c;之后有关人工智能结合的数字图像处理咸鱼哥正在学习和创作中&#xff0c;所以还请大家给咸鱼哥点时间&#xff0c;同时也提前预祝大家2025年新春快乐&#xff01;&#xff08;咸鱼哥真诚的祝愿每一个人&#xf…

通义灵码插件保姆级教学-IDEA(安装及使用)

一、JetBrains IDEA 中安装指南 官方下载指南&#xff1a;通义灵码安装教程-阿里云 步骤 1&#xff1a;准备工作 操作系统&#xff1a;Windows 7 及以上、macOS、Linux&#xff1b; 下载并安装兼容的 JetBrains IDEs 2020.3 及以上版本&#xff0c;通义灵码与以下 IDE 兼容&…

利用双指针一次遍历实现”找到“并”删除“单链表倒数第K个节点(力扣题目为例)

Problem: 19. 删除链表的倒数第 N 个结点 文章目录 题目描述思路复杂度Code 题目描述 思路 1.欲找到倒数第k个节点&#xff0c;即是找到正数的第n-k1、其中n为单链表中节点的个数个节点。 2.为实现只遍历一次单链表&#xff0c;我们先可以使一个指针p1指向链表头部再让其先走k步…

2025美赛倒计时,数学建模五类模型40+常用算法及算法手册汇总

数学建模美赛倒计时&#xff0c;对于第一次参加竞赛且没有相关基础知识的同学来讲&#xff0c;掌握数学建模常用经典的模型算法知识&#xff0c;并熟练使用相关软件进行建模是关键。本文将介绍一些常用的模型算法&#xff0c;以及软件操作教程。 数学建模常用模型包括&#xf…

前端【10】jQuery DOM 操作

目录 jquery捕获查取 获得内容 - text()、html() 以及 val() 获取属性 - attr() ​编辑 jQuery 修改/设置内容和属性 设置内容 - text()、html() 以及 val() 设置属性 - attr() jQuery添加元素 jQuery - 删除元素 前端【9】初识jQuery&#xff1a;让JavaScript变得更简…

汇编的使用总结

一、汇编的组成 1、汇编指令&#xff08;指令集&#xff09; 数据处理指令: 数据搬移指令 数据移位指令 位运算指令 算术运算指令 比较指令 跳转指令 内存读写指令 状态寄存器传送指令 异常产生指令等 2、伪指令 不是汇编指令&#xff0c;但是可以起到指令的作用&#xff0c;伪…