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

c/c++蓝桥杯经典编程题100道(19)汉诺塔问题

汉诺塔问题

->返回c/c++蓝桥杯经典编程题100道-目录


目录

汉诺塔问题

一、题型解释

二、例题问题描述

三、C语言实现

解法1:递归法(难度★)

解法2:迭代法(难度★★★)

四、C++实现

解法1:递归法(使用STL容器记录步骤,难度★☆)

解法2:面向对象封装(难度★★)

五、总结对比表

六、特殊方法与内置函数补充

1. C语言中的结构体栈

2. C++的 std::vector

3. 汉诺塔数学公式


一、题型解释

汉诺塔(Tower of Hanoi)是经典的递归问题,描述如下:

  • 三根柱子:A(起点)、B(辅助)、C(终点)。

  • 若干盘子:初始时所有盘子按大小顺序叠放在A柱,大的在下,小的在上。

  • 目标:将所有盘子从A柱移动到C柱,每次只能移动一个盘子,且任何时候大盘子不能放在小盘子上

常见题型:

  1. 基础问题:计算移动步骤或最少步数(n个盘子需移动 2^n - 1 次)。

  2. 多柱扩展:四根或多根柱子的变种问题(如Frame-Stewart算法)。

  3. 路径限制:限制某些移动规则(如只能从A→B、B→C、C→A)。


二、例题问题描述

例题1:输入盘子数 n=3,输出移动步骤:

A → C  
A → B  
C → B  
A → C  
B → A  
B → C  
A → C

例题2:输入 n=4,输出最少移动次数 15
例题3:验证移动序列 [A→B, A→C, B→C] 是否是 n=2 的有效解(输出 true)。


三、C语言实现

解法1:递归法(难度★)

通俗解释

  • 将问题分解为三步:

    1. 将前 n-1 个盘子从A移动到B(借助C)。

    2. 将第 n 个盘子从A移动到C。

    3. 将 n-1 个盘子从B移动到C(借助A)。

c

#include <stdio.h>// 递归函数:将n个盘子从src移动到dst,使用aux作为辅助
void hanoi(int n, char src, char aux, char dst) {if (n == 1) { // 基线条件:只剩一个盘子直接移动printf("%c → %c\n", src, dst);return;}hanoi(n - 1, src, dst, aux); // 将n-1个盘子从src移动到aux(借助dst)printf("%c → %c\n", src, dst); // 移动第n个盘子到dsthanoi(n - 1, aux, src, dst); // 将n-1个盘子从aux移动到dst(借助src)
}int main() {int n = 3;hanoi(n, 'A', 'B', 'C');return 0;
}

代码逻辑

  1. 基线条件:当 n=1 时,直接移动盘子。

  2. 递归分解

    • 第一步:将 n-1 个盘子从起点移动到辅助柱(递归调用)。

    • 第二步:移动最大的盘子到目标柱。

    • 第三步:将 n-1 个盘子从辅助柱移动到目标柱(递归调用)。

  3. 时间复杂度:O(2^n),因为每一步分解为两个子问题。


解法2:迭代法(难度★★★)

通俗解释

  • 用栈模拟递归过程,手动管理每一步的状态(当前盘子数、源柱、辅助柱、目标柱)。

c

#include <stdio.h>
#include <stdlib.h>// 定义栈结构体,存储每一步的状态
typedef struct {int n;char src, aux, dst;
} StackFrame;void hanoiIterative(int n, char src, char aux, char dst) {StackFrame stack[100]; // 假设n不超过100层int top = -1; // 栈顶指针// 初始状态:移动n个盘子从src到dst,使用aux辅助StackFrame init = {n, src, aux, dst};stack[++top] = init;while (top >= 0) {StackFrame current = stack[top--]; // 弹出当前任务if (current.n == 1) {printf("%c → %c\n", current.src, current.dst);} else {// 分解为三个子任务(注意顺序与递归相反)// 子任务3:移动n-1个盘子从aux到dst,使用src辅助StackFrame task3 = {current.n - 1, current.aux, current.src, current.dst};stack[++top] = task3;// 子任务2:移动第n个盘子从src到dstStackFrame task2 = {1, current.src, current.aux, current.dst};stack[++top] = task2;// 子任务1:移动n-1个盘子从src到aux,使用dst辅助StackFrame task1 = {current.n - 1, current.src, current.dst, current.aux};stack[++top] = task1;}}
}int main() {hanoiIterative(3, 'A', 'B', 'C');return 0;
}

代码逻辑

  1. 栈模拟递归:显式管理待处理的任务(类似递归调用栈)。

  2. 任务分解顺序:由于栈是后进先出,子任务需按相反顺序入栈。

  3. 优势:避免递归的栈溢出风险,适合大规模n。


四、C++实现

解法1:递归法(使用STL容器记录步骤,难度★☆)

通俗解释

  • 使用 vector 存储移动步骤,方便后续处理或输出。

cpp

#include <iostream>
#include <vector>
using namespace std;vector<string> steps; // 存储移动步骤void hanoi(int n, char src, char aux, char dst) {if (n == 1) {steps.push_back(string(1, src) + " → " + dst);return;}hanoi(n - 1, src, dst, aux);steps.push_back(string(1, src) + " → " + dst);hanoi(n - 1, aux, src, dst);
}int main() {hanoi(3, 'A', 'B', 'C');for (const string& step : steps) {cout << step << endl;}return 0;
}

代码逻辑

  • 与C语言递归逻辑相同,但使用 vector<string> 动态存储步骤。

  • 输出灵活性:可随时访问或修改步骤记录。


解法2:面向对象封装(难度★★)

通俗解释

  • 将汉诺塔问题封装为类,支持多种操作(如统计步数、验证步骤)。

cpp

#include <iostream>
#include <vector>
using namespace std;class HanoiSolver {
private:vector<string> steps;void move(int n, char src, char aux, char dst) {if (n == 1) {steps.push_back(string(1, src) + " → " + dst);return;}move(n - 1, src, dst, aux);steps.push_back(string(1, src) + " → " + dst);move(n - 1, aux, src, dst);}
public:void solve(int n) {steps.clear();move(n, 'A', 'B', 'C');}void printSteps() {for (const string& step : steps) {cout << step << endl;}}
};int main() {HanoiSolver solver;solver.solve(3);solver.printSteps();return 0;
}

代码逻辑

  1. 封装性:将步骤记录和求解逻辑封装在类中。

  2. 扩展性:可添加方法统计步数、验证移动序列等。


五、总结对比表

方法时间复杂度空间复杂度优点缺点
递归法O(2^n)O(n)代码简洁,易理解栈溢出风险
迭代法O(2^n)O(n)避免递归栈溢出代码复杂,需手动管理栈
STL容器记录O(2^n)O(2^n)灵活处理步骤内存占用高
面向对象封装O(2^n)O(2^n)扩展性强,易于维护代码稍长

六、特殊方法与内置函数补充

1. C语言中的结构体栈

  • 作用:手动实现栈结构,存储递归状态(需注意栈大小限制)。

2. C++的 std::vector

  • 动态数组:自动扩展容量,适合存储不定长的移动步骤。

3. 汉诺塔数学公式

  • 最少步数2^n - 1,可通过位运算快速计算(如 (1 << n) - 1)。

->返回c/c++蓝桥杯经典编程题100道-目录

 

相关文章:

c/c++蓝桥杯经典编程题100道(19)汉诺塔问题

汉诺塔问题 ->返回c/c蓝桥杯经典编程题100道-目录 目录 汉诺塔问题 一、题型解释 二、例题问题描述 三、C语言实现 解法1&#xff1a;递归法&#xff08;难度★&#xff09; 解法2&#xff1a;迭代法&#xff08;难度★★★&#xff09; 四、C实现 解法1&#xff1…...

Linux 信号量

Linux 信号量 一、信号量基础概念1.1 同步机制的核心需求1.2 信号量的核心原理1.3 信号量类型对比 二、实战代码解析2.1 共享内存与信号量结合示例2.2 信号量类实现要点 三、关键实现细节分析3.1 初始化三步骤3.2 SEM_UNDO机制3.3 原子操作保证 四、进阶应用场景4.1 生产者-消费…...

Qt开发①Qt的概念+发展+优点+应用+使用

目录 1. Qt的概念和发展 1.1 Qt的概念 1.2 Qt 的发展史&#xff1a; 1.3 Qt 的版本 2. Qt 的优点和应用 2.1 Qt 的优点&#xff1a; 2.2 Qt 的应用场景 2.3 Qt 的应用案例 3. 搭建 Qt 开发环境 3.1 Qt 的开发工具 3.2 Qt SDK 的下载和安装 3.3 Qt 环境变量配置和使…...

向量库(Vector Database)

向量库 1. 向量库发展史 早期阶段&#xff08;2000s&#xff09; 基于关系型数据库的扩展&#xff08;如 PostgreSQL 的向量插件&#xff09;。简单相似度计算&#xff08;如欧氏距离、余弦相似度&#xff09;。 专用向量库的兴起&#xff08;2010s&#xff09; FAISS&#xf…...

torchsparse安装过程的问题

1、项目要求torchsparse githttps://github.com/mit-han-lab/torchsparse.gitv1.4.0 2、torch1.8.1cu111 nvcc--version&#xff1a;11.1 这个版本的cuda匹配的gcc、g经常是7.5。设置为7.5. &#xff08;这个gcc、g版本修改不一定&#xff0c;可以先进行后面的&#xff0c…...

【核心算法篇七】《DeepSeek异常检测:孤立森林与AutoEncoder对比》

大家好,今天我们来深入探讨一下《DeepSeek异常检测:孤立森林与AutoEncoder对比》这篇技术博客。我们将从核心内容、原理、应用场景等多个方面进行详细解析,力求让大家对这两种异常检测方法有一个全面而深入的理解。 一、引言 在数据科学和机器学习领域,异常检测(Anomaly…...

Win10环境使用零讯ZeroNews内网穿透实现Deepseek对外服务

Win10环境使用零讯ZeroNews内网穿透实现Deepseek对外服务 前言 之前笔者已经在Win10环境搭建好了Ollama、DeepSeek、Open WebUI、Dify等组件&#xff0c;成功实现了私有化部署及内网访问&#xff1a; https://lizhiyong.blog.csdn.net/article/details/145505686 https://l…...

CUDA 安装 一直卡在Installing Nsight Visual Studio Edition

最近在安装CUDA的时候&#xff0c;CUDA 安装 一直卡在Installing Nsight Visual Studio Edition&#xff0c;莫名的一直卡在安装进行中这儿&#xff0c;过很久都没进度&#xff0c;如图 后面重新下载了12.6的进行安装也是如此 无论是local还是network&#xff0c;都是这样。度…...

Softing线上研讨会 | 自研还是购买——用于自动化产品的工业以太网

| 线上研讨会时间&#xff1a;2025年1月27日 16:00~16:30 / 23:00~23:30 基于以太网的通信在工业自动化网络中的重要性日益增加。设备制造商正面临着一大挑战——如何快速、有效且经济地将工业以太网协议集成到其产品中。其中的关键问题包括&#xff1a;是否只需集成单一的工…...

STM32 定时器产生定周期方法

目录 背景 程序 第一步、使能PCLK1外设时钟​编辑 第二步、时基单元配置 第三步、配置NVIC&#xff08;设置定时中断优先级&#xff09;​编辑 第四步、使能溢出中断 第五步、使能定时器 第六步、填写中断处理函数&#xff08;ISR&#xff09; 背景 在单片机开发当中&…...

解锁机器学习核心算法 | 支持向量机:机器学习中的分类利刃

一、引言 在机器学习的庞大算法体系中&#xff0c;有十种算法被广泛认为是最具代表性和实用性的&#xff0c;它们犹如机器学习领域的 “十大神器”&#xff0c;各自发挥着独特的作用。这十大算法包括线性回归、逻辑回归、决策树、随机森林、K - 近邻算法、K - 平均算法、支持向…...

青少年编程与数学 02-009 Django 5 Web 编程 21课题、部署

青少年编程与数学 02-009 Django 5 Web 编程 21课题、部署 一、软件开发部署部署的主要内容部署的步骤部署的方式部署的环境 二、Django项目部署1. 准备工作2. 代码部署3. 配置Django项目4. Web服务器和应用服务器配置5. 安全和性能优化6. 监控和日志管理7. 测试和上线 三、在U…...

ARM系统源码编译OpenCV 4.10.0(包含opencv_contrib)

因项目部署在ARM系统上&#xff0c;需要编译一个arm版本的opencv-4.10.0&#xff08;带opencv_contrib&#xff09;版本。 若需要Linux系统下源码安装OpenCV&#xff0c;可参考&#xff1a;https://blog.csdn.net/qq_45445740/article/details/142770493?spm1001.2014.3001.55…...

cmake:定位Qt的ui文件

如题。在工程中&#xff0c;将h&#xff0c;cpp&#xff0c;ui文件放置到不同文件夹下&#xff0c;会存在cmake找不到ui文件&#xff0c;导致编译报错情况。 cmake通过指定文件路径&#xff0c;确保工程找到ui文件。 标识1&#xff1a;ui文件保存路径。 标识2&#xff1a;添加…...

(leetcode 1749 前缀和)1749. 任意子数组和的绝对值的最大值

核心题意 任意子数组和 的绝对值的最大值实际上是前缀和之间的差的最大值 建立前缀和数组 如果我们只考虑前缀和的最大值和最小值之差&#xff0c;那么就能够获得一个最大的子数组和的绝对值。因为任意一个子数组的和 prefix[j1] - prefix[i]&#xff0c;它的绝对值是最大当…...

下载安装运行测试开源vision-language-action(VLA)模型OpenVLA

1. 安装 项目官网OpenVLA 首先按照官网提示的以下代码&#xff0c;执行创建环境->安装最小依赖->git克隆项目等 # Create and activate conda environment conda create -n openvla python3.10 -y conda activate openvla# Install PyTorch. Below is a sample comma…...

【网络安全 | 漏洞挖掘】我如何通过Cookie Manipulation发现主域上的关键PII?

未经许可,不得转载。 文章目录 正文正文 在分析 Example.com 的认证机制时,我注意到一个特定的 cookie,USER_ID,包含了一个具有预测性的会话标识符,其格式为: USER_ID="VYCVCDs-TZBI:XXXX-random-data"其中,XXXX 是由四个大写字母组成的部分,我使用 Burp S…...

【操作系统】操作系统概述

操作系统概述 1.1 操作系统的概念1.1.1 操作系统定义——什么是OS&#xff1f;1.1.2 操作系统作用——OS有什么用&#xff1f;1.1.3 操作系统地位——计算机系统中&#xff0c;OS处于什么地位&#xff1f;1.1.4 为什么学操作系统&#xff1f; 1.2 操作系统的历史1.2.1 操作系统…...

SQL Server 运算符优先级

在 SQL Server 中&#xff0c;运算符的优先级决定了在没有使用括号明确指定计算顺序时&#xff0c;运算符的执行顺序。 运算符优先级列表 括号 () 一元运算符 &#xff08;正号&#xff09;-&#xff08;负号&#xff09;~&#xff08;按位取反&#xff09; 乘法、除法和取模…...

Python的顺序结构和循环结构

文章目录 一、条件语句&#xff08;1&#xff09;条件语句的定义&#xff08;2&#xff09;条件语句的语法&#xff08;a&#xff09;单分支 if&#xff08;b&#xff09;双分支 if-else&#xff08;c&#xff09;多分支 if-elif-elif-...-else &#xff08;3&#xff09;注意事…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...