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柱,每次只能移动一个盘子,且任何时候大盘子不能放在小盘子上。
常见题型:
-
基础问题:计算移动步骤或最少步数(n个盘子需移动
2^n - 1
次)。 -
多柱扩展:四根或多根柱子的变种问题(如Frame-Stewart算法)。
-
路径限制:限制某些移动规则(如只能从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:递归法(难度★)
通俗解释:
-
将问题分解为三步:
-
将前
n-1
个盘子从A移动到B(借助C)。 -
将第
n
个盘子从A移动到C。 -
将
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;
}
代码逻辑:
-
基线条件:当
n=1
时,直接移动盘子。 -
递归分解:
-
第一步:将
n-1
个盘子从起点移动到辅助柱(递归调用)。 -
第二步:移动最大的盘子到目标柱。
-
第三步:将
n-1
个盘子从辅助柱移动到目标柱(递归调用)。
-
-
时间复杂度: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;
}
代码逻辑:
-
栈模拟递归:显式管理待处理的任务(类似递归调用栈)。
-
任务分解顺序:由于栈是后进先出,子任务需按相反顺序入栈。
-
优势:避免递归的栈溢出风险,适合大规模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;
}
代码逻辑:
-
封装性:将步骤记录和求解逻辑封装在类中。
-
扩展性:可添加方法统计步数、验证移动序列等。
五、总结对比表
方法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
---|---|---|---|---|
递归法 | 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:递归法(难度★) 解法2:迭代法(难度★★★) 四、C实现 解法1࿱…...
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 的发展史: 1.3 Qt 的版本 2. Qt 的优点和应用 2.1 Qt 的优点: 2.2 Qt 的应用场景 2.3 Qt 的应用案例 3. 搭建 Qt 开发环境 3.1 Qt 的开发工具 3.2 Qt SDK 的下载和安装 3.3 Qt 环境变量配置和使…...

向量库(Vector Database)
向量库 1. 向量库发展史 早期阶段(2000s) 基于关系型数据库的扩展(如 PostgreSQL 的向量插件)。简单相似度计算(如欧氏距离、余弦相似度)。 专用向量库的兴起(2010s) FAISS…...
torchsparse安装过程的问题
1、项目要求torchsparse githttps://github.com/mit-han-lab/torchsparse.gitv1.4.0 2、torch1.8.1cu111 nvcc--version:11.1 这个版本的cuda匹配的gcc、g经常是7.5。设置为7.5. (这个gcc、g版本修改不一定,可以先进行后面的,…...

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

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

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

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

STM32 定时器产生定周期方法
目录 背景 程序 第一步、使能PCLK1外设时钟编辑 第二步、时基单元配置 第三步、配置NVIC(设置定时中断优先级)编辑 第四步、使能溢出中断 第五步、使能定时器 第六步、填写中断处理函数(ISR) 背景 在单片机开发当中&…...

解锁机器学习核心算法 | 支持向量机:机器学习中的分类利刃
一、引言 在机器学习的庞大算法体系中,有十种算法被广泛认为是最具代表性和实用性的,它们犹如机器学习领域的 “十大神器”,各自发挥着独特的作用。这十大算法包括线性回归、逻辑回归、决策树、随机森林、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系统上,需要编译一个arm版本的opencv-4.10.0(带opencv_contrib)版本。 若需要Linux系统下源码安装OpenCV,可参考:https://blog.csdn.net/qq_45445740/article/details/142770493?spm1001.2014.3001.55…...

cmake:定位Qt的ui文件
如题。在工程中,将h,cpp,ui文件放置到不同文件夹下,会存在cmake找不到ui文件,导致编译报错情况。 cmake通过指定文件路径,确保工程找到ui文件。 标识1:ui文件保存路径。 标识2:添加…...
(leetcode 1749 前缀和)1749. 任意子数组和的绝对值的最大值
核心题意 任意子数组和 的绝对值的最大值实际上是前缀和之间的差的最大值 建立前缀和数组 如果我们只考虑前缀和的最大值和最小值之差,那么就能够获得一个最大的子数组和的绝对值。因为任意一个子数组的和 prefix[j1] - prefix[i],它的绝对值是最大当…...

下载安装运行测试开源vision-language-action(VLA)模型OpenVLA
1. 安装 项目官网OpenVLA 首先按照官网提示的以下代码,执行创建环境->安装最小依赖->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?1.1.2 操作系统作用——OS有什么用?1.1.3 操作系统地位——计算机系统中,OS处于什么地位?1.1.4 为什么学操作系统? 1.2 操作系统的历史1.2.1 操作系统…...
SQL Server 运算符优先级
在 SQL Server 中,运算符的优先级决定了在没有使用括号明确指定计算顺序时,运算符的执行顺序。 运算符优先级列表 括号 () 一元运算符 (正号)-(负号)~(按位取反) 乘法、除法和取模…...

Python的顺序结构和循环结构
文章目录 一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(c)多分支 if-elif-elif-...-else (3)注意事…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...