当前位置: 首页 > article >正文

【蓝桥杯】43697.机器人塔

题目描述

X 星球的机器人表演拉拉队有两种服装,A 和 B。

他们这次表演的是搭机器人塔。

类似:

A

B B

A B A

A A B B

B B B A B

A B A B B A

队内的组塔规则是:

A 只能站在 AA 或 BB 的肩上。

B 只能站在 AB 或 BA 的肩上。

你的任务是帮助拉拉队计算一下,在给定 A 与 B 的人数时,可以组成多少种花样的塔。

输入描述

输入一行两个整数 M,N(0<M,N<500),分别表示 A、B 的人数,保证人数合理性。

输出描述

要求输出一个整数,表示可以产生的花样种数。

输入输出样例

示例
输入

1 2

输出

3

题目解析

  通读一遍题目,已知“初始局面”,求“未来可能的局面”的数量,不出意外的话,这又是一道关于“遍历”类型的题目,那么我们首先会考虑到 深度优先搜索DFS 或者 广度优先搜索BFS 算法。

比如说,有一个A,两个B,那么有多少种组合方式呢?
看下规则的说明:

  1. A 只能站在 AA 或 BB 的肩上。
  2. B 只能站在 AB 或 BA 的肩上。

在这个案例中,有一个A和两个B,先从A开始遍历。
如果第一行是A,那么在剩下的字符中,第二行只有BB这一种组合;
A
B B
如果第一行是B,那么在剩下的字符中,第二行可以有AB或者BA这两种组合;
B     或者      B
A B            B A
那么一共有3种组合的可能性局面。

   在这其中有一个重要的规律:如果底层相邻的两个字符相同(比如都是AA或BB),则上层对应的一定是A; 如果底层相邻的两个字符不同(比如是AB或BA),则上层对应的一定是B。

   使用DFS算法解决该问题,算法的核心目标是根据输入的 A 和 B 的数量,找出所有可能的机器人塔花样。其步骤包括:计算塔的层数、使用深度优先搜索生成所有可能的底层排列、对每个底层排列检查是否能构建出满足规则且 A、B 数量符合要求的塔,最后输出符合条件的塔的数量。

算法步骤

  1. 读取输入
    在 main 函数中,首先通过 map(int, input().split()) 读取用户输入的一行两个整数,分别赋值给变量 m 和 n,它们分别代表 A 和 B 的数量。
  2. 计算塔的层数
    根据机器人塔的结构特点,总的机器人数等于从 1 到塔层数的连续整数之和,即满足公式 total = layer * (layer + 1) // 2,其中 total = m + n。通过一个循环不断增加 layer 的值,直到找到满足该公式的层数。
  3. 深度优先搜索
       调用 dfs 函数开始深度优先搜索,初始参数为当前层(初始设为 1)、目标底层长度(即上面计算得到的塔的层数 layer)、A 和 B 的目标数量 m 和 n,以及一个空列表表示初始的底层排列。
       终止条件判断:当当前正在构建的底层排列 current_bottom 的长度达到目标底层长度 target_layer 时,说明已经生成了一个完整的底层排列。此时调用 check_tower 函数检查该底层排列是否能构建出满足条件的塔,如果满足则将全局结果计数器 result 加 1。
       递归搜索:如果底层排列还未构建完成,则分别尝试在 current_bottom 后面添加 ‘A’ 和 ‘B’,并递归调用 dfs 函数继续生成底层排列。
  4. 检查塔是否满足条件
       构建塔:从给定的底层排列 bottom 开始,根据组塔规则逐层向上构建塔。对于每一层,根据相邻两个元素的情况生成上一层的元素:如果相邻两个元素相同则生成 ‘A’,不同则生成 ‘B’。
       统计 A 和 B 的数量:遍历整个塔的每一层,统计其中 A 和 B 的数量。
       判断是否满足条件:最后判断统计得到的 A 和 B 的数量是否与目标数量 m 和 n 相等,如果相等则返回 True,表示该底层排列能构建出满足条件的塔,否则返回 False。
  5. 输出统计结果

代码实现

DFS 调用实现

# 全局变量用于存储最终结果
result = 0

# 深度优先搜索函数,生成底层排列并检查是否满足条件
def dfs(current_layer, target_layer, m, n, current_bottom):
    global result
    # 当生成的底层排列达到目标长度时
    if len(current_bottom) == target_layer:
        # 调用检查函数判断是否满足条件
        if check_tower(current_bottom, m, n):
            result += 1
        return
    # 尝试添加 'A' 到当前底层排列
    dfs(current_layer, target_layer, m, n, current_bottom + ['A'])
    # 尝试添加 'B' 到当前底层排列
    dfs(current_layer, target_layer, m, n, current_bottom + ['B'])

# 检查基于给定底层排列构建的塔是否满足 A 和 B 的数量要求
def check_tower(bottom, m, n):
    tower = [bottom]
    current = bottom
    # 逐层向上构建塔
    while len(current) > 1:
        next_layer = []
        for i in range(len(current) - 1):
            if current[i] == current[i + 1]:
                next_layer.append('A')
            else:
                next_layer.append('B')
        tower.append(next_layer)
        current = next_layer
    # 统计塔中 A 和 B 的数量
    count_a = 0
    count_b = 0
    for layer in tower:
        count_a += layer.count('A')
        count_b += layer.count('B')
    # 判断数量是否与目标一致
    return count_a == m and count_b == n

# 主函数,读取输入并启动深度优先搜索
def main():
    global result
    m, n = map(int, input().split())
    total = m + n
    layer = 1
    # 计算塔的层数
    while layer * (layer + 1) // 2 != total:
        layer += 1
    # 启动深度优先搜索
    dfs(1, layer, m, n, [])
    print(result)

if __name__ == "__main__":
    main()

非DFS算法

# 检查一个可能的底层排列是否能组成满足规则的塔
def check_bottom(bottom, m, n):
    tower = [bottom]
    current = bottom
    # 逐层构建塔
    while len(current) > 1:
        next_layer = []
        for i in range(len(current) - 1):
            if current[i] == current[i + 1]:
                next_layer.append('A')
            else:
                next_layer.append('B')
        tower.append(next_layer)
        current = next_layer
    # 统计 A 和 B 的数量
    count_a = 0
    count_b = 0
    for layer in tower:
        count_a += layer.count('A')
        count_b += layer.count('B')
    return count_a == m and count_b == n

# 生成所有可能的底层排列
def generate_bottoms(length):
    from itertools import product
    return product(['A', 'B'], repeat=length)

# 主函数
def main():
    m, n = map(int, input().split())
    # 计算塔的层数
    total = m + n
    layer = 1
    while layer * (layer + 1) // 2 != total:
        layer += 1
    # 生成所有可能的底层排列
    bottoms = generate_bottoms(layer)
    # 检查每个底层排列是否满足条件
    result = 0
    for bottom in bottoms:
        if check_bottom(list(bottom), m, n):
            result += 1
    print(result)

if __name__ == "__main__":
    main()

http://www.kler.cn/a/527314.html

相关文章:

  • 栈和队列特别篇:栈和队列的经典算法问题
  • 【PyTorch】6.张量运算函数:一键开启!PyTorch 张量函数的宝藏工厂
  • chrome源码剖析—进程通信
  • C++,STL 简介:历史、组成、优势
  • 本地部署deepseek模型步骤
  • STM32标准库移植RT-Thread nano
  • origin如何在已经画好的图上修改数据且不改变原图像的画风和格式
  • 知识库管理如何推动企业数字化转型与创新发展的深层次探索
  • 智联出行公司布局中国市场,引领绿色出行新潮流
  • riscv xv6学习笔记
  • 使用vhd虚拟磁盘安装两个win10系统
  • cmd命令行无法进入D:盘怎么办
  • 论文阅读笔记 —— 英文论文常见缩写及含义
  • 优盘恢复原始容量工具
  • 为AI聊天工具添加一个知识系统 之73 详细设计之14 正则表达式 之1
  • deepseek本地部署使用教程
  • three.js+WebGL踩坑经验合集(6.1):负缩放,负定矩阵和行列式的关系(2D版本)
  • 可被electron等调用的Qt截图-录屏工具【源码开放】
  • 根据每月流量和市场份额排名前20 的AI工具列表
  • langgraph实现 handsoff between agents 模式 (1)
  • 自定义数据集 使用paddlepaddle框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测
  • 99.20 金融难点通俗解释:中药配方比喻马科维茨资产组合模型(MPT)
  • Jenkins 的安装(详细教程)_jenkins安装
  • 彩色控制台,自动换行...学习个新概念:流操控器![more cpp--11]
  • Python酷库之旅-第三方库Pandas(103)
  • Redis 基础命令