汉诺塔问题:递归

news2024/11/18 0:16:30

经典汉诺塔问题

汉诺塔问题是经典的可以用递归解决的问题。

汉诺塔(Hanoi)游戏规则如下:在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。计算需要移动的次数。

我们先来对汉诺塔的步数进行一下递推。

对于 n n n个盘子,我们可以把它分成 n − 1 n-1 n1个盘子和最后一个大盘子。设 F ( n ) F(n) F(n)为移动所需步数,那么对于 n n n个盘子来说所做的事情就是

  1. n − 1 n-1 n1个盘子从A柱借助C柱移动到B柱,这一过程移动的步数为 F ( n − 1 ) F(n-1) F(n1)
  2. 将大盘子从A柱直接移动到C柱,此时需要1步。
  3. n − 1 n-1 n1个盘子从B柱借助A柱移动到C柱,此时需要的步数仍为 F ( n − 1 ) F(n-1) F(n1)

综合以上分析, F ( n ) = 2 F ( n − 1 ) + 1 F(n)=2F(n-1)+1 F(n)=2F(n1)+1。对两边同时加上1可以凑成一个等比数列,然后就可以求出其通项公式。

完整C++代码:

#include <iostream>
#include <cmath>
using namespace std;

void Hanoi(char a, char b, char c, int n) // 把n个盘从a经过b移动到c
{
  if (n == 0)
    return;
  Hanoi(a, c, b, n - 1);
  cout << a << " -> " << c << endl;
  Hanoi(b, a, c, n - 1);
}
int main()
{
  int n;
  cin >> n;
  Hanoi('a', 'b', 'c', n);
}

如果要计算移动的次数可以定义一个全局变量ans来保存:

#include <iostream>
#include <cmath>
using namespace std;
int ans = 0;
void Hanoi(char a, char b, char c, int n) // 把n个盘从a经过b移动到c
{
  if (n == 0)
    return;
  Hanoi(a, c, b, n - 1);
  ans++;
  cout << a << " -> " << c << endl;
  Hanoi(b, a, c, n - 1);
}
int main()
{
  int n;
  cin >> n;
  Hanoi('a', 'b', 'c', n);
  cout << ans;
}

输入:3
输出:
在这里插入图片描述

改后的汉诺塔问题

改进的汉诺塔问题如下:

汉诺塔(Hanoi)游戏规则如下:在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,且限定圆盘只能够移动到相邻的柱子,即A柱子上的圆盘只能够移动到B,B柱子上的圆盘只能够移动到A或者C,C同理。并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。计算需要移动的次数。

我们先来对改后的汉诺塔的步数进行一下递推。

对于 n n n个盘子,我们还是可以把它分成 n − 1 n-1 n1个盘子和最后一个大盘子。设 F ( n ) F(n) F(n)为移动所需步数,那么对于 n n n个盘子来说所做的事情就是

  1. n − 1 n-1 n1个盘子从A柱借助B柱移动到C柱,这一过程移动的步数为 F ( n − 1 ) F(n-1) F(n1)
  2. 将大盘子从A柱直接移动到B柱,此时需要1步。
  3. n − 1 n-1 n1个盘子从C柱借助B柱移动到A柱,此时需要的步数仍为 F ( n − 1 ) F(n-1) F(n1)
  4. 将大盘子从B柱直接移动到C柱,此时需要1步。
  5. n − 1 n-1 n1个盘子从A柱借助B柱移动到C柱,此时需要的步数仍为 F ( n − 1 ) F(n-1) F(n1)

综合以上分析, F ( n ) = 3 F ( n − 1 ) + 2 F(n)=3F(n-1)+2 F(n)=3F(n1)+2。对两边同时加上1可以凑成一个等比数列,然后就可以求出其通项公式。

完整C++代码:

#include <iostream>
#include <cmath>
using namespace std;

void Hanoi(char a, char b, char c, int n) // 把n个盘从a经过b移动到c
{
  if (n == 0)
    return;
  Hanoi(a, b, c, n - 1);
  cout << a << " -> " << b << endl;
  Hanoi(c, b, a, n - 1);
  cout << b << " -> " << c << endl;
  Hanoi(a, b, c, n - 1);
}
int main()
{
  int n;
  cin >> n;
  Hanoi('a', 'b', 'c', n);
}

如果要计算移动的次数可以定义一个全局变量ans来保存:

#include <iostream>
#include <cmath>
using namespace std;
int ans = 0;
void Hanoi(char a, char b, char c, int n) // 把n个盘从a经过b移动到c
{
  if (n == 0)
    return;

  Hanoi(a, b, c, n - 1);
  ans++;
  cout << a << " -> " << b << endl;
  Hanoi(c, b, a, n - 1);
  ans++;
  cout << b << " -> " << c << endl;
  Hanoi(a, b, c, n - 1);
}
int main()
{
  int n;
  cin >> n;
  Hanoi('a', 'b', 'c', n);
  cout << ans;
}

输入:3
输出:
在这里插入图片描述

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

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

相关文章

系统架构师备考倒计时25天(每日知识点)

面向对象设计原则 单一职责原则&#xff1a;设计目的单一的类开放-封闭原则&#xff1a;对扩展开放&#xff0c;对修改封闭李氏(Liskov)替换原则&#xff1a;子类可以替换父类依赖倒置原则&#xff1a;要依赖于抽象&#xff0c;而不是具体实现&#xff1b;针对接口编程&#x…

【Redis】Redis持久化深度解析

原创不易&#xff0c;注重版权。转载请注明原作者和原文链接 文章目录 Redis持久化介绍RDB原理Fork函数与写时复制关于写时复制的思考 RDB相关配置 AOF原理AOF持久化配置AOF文件解读AOF文件修复AOF重写AOF缓冲区与AOF重写缓存区AOF缓冲区可以替代AOF重写缓冲区吗AOF相关配置写后…

机器学习之自训练协同训练

前言 监督学习往往需要大量的标注数据&#xff0c; 而标注数据的成本比较高 &#xff0e; 因此 &#xff0c; 利用大量的无标注数据来提高监督学习的效果有着十分重要的意义&#xff0e; 这种利用少量标注数据和大量无标注数据进行学习的方式称为 半监督学习 &#xff08; Semi…

Java 序列化和反序列化为什么要实现 Serializable 接口?

序列化和反序列化 序列化&#xff1a;把对象转换为字节序列的过程称为对象的序列化. 反序列化&#xff1a;把字节序列恢复为对象的过程称为对象的反序列化. 什么时候需要用到序列化和反序列化呢或者对象序列化的两种用途… &#xff1a; (1) 对象持久化&#xff1a;把对象的…

NSSCTF做题(8)

[SWPUCTF 2022 新生赛]js_sign 看到了js代码 有一个base64编码&#xff0c;解密 最后发现这是一个加密方式 去掉空格之后得到了flag NSSCTF{youfindflagbytapcode} [MoeCTF 2022]baby_file 提示说有一个秘密看看你能不能找到 输入?filesecret 出现报错 输入php伪协议读取i…

Simulink仿真之离散系统

最近&#xff0c;为了完成课程作业&#xff0c;需要用到Simulink验证数字控制器的合理性。题目如下所示。 其实这道题在胡寿松老师的《自动控制原理&#xff08;第七版&#xff09;》的364页有答案。 这里给出数字控制器的脉冲传递函数为 ​​​​​​​ ​​​​​​​…

【22】c++设计模式——>外观模式

外观模式定义 为复杂系统提供一个简化接口&#xff0c;它通过创建一个高层接口(外观)&#xff0c;将多个子系统的复杂操作封装起来&#xff0c;以便客户端更容易使用。 简单实现 #include<iostream>// 子系统类 class SubsystemA { public:void operationA() {std::co…

经典循环命题:百钱百鸡

翁五钱一只&#xff0c;母三钱&#xff0c;小鸡三只一钱&#xff1b;百钱百鸡百鸡花百钱。 (本笔记适合能熟练应用for循环、会使if条件分支语句、能格式化字符输出的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a…

自定义表单工具好用的优点是什么?

如果想提升办公效率&#xff0c;那么就离不开低代码技术平台了。它的轻量级、易掌握、易操作、简洁简便等优势特点深得很多领域客户朋友的喜爱。目前&#xff0c;IBPS开发平台在通信业、制造业、医疗、高校等很多行业中得到了客户的肯定和喜爱&#xff0c;推广价值高&#xff0…

懒人福利:不用动脑就能制作电子画册

对于很多企业来说&#xff0c;想要快速把自己的活动大面积的宣传出去&#xff0c;就要快人一步提前制作电子版画册&#xff0c;通过网络推送出去&#xff0c;让大众及时了解。如何制作电子版画册呢&#xff1f; 我发现了一个懒人福利&#xff01;就是FLBOOK &#xff0c;它简单…

学习函数式编程、可变参数及 defer - GO语言从入门到实战

函数是⼀等公⺠、学习函数式编程、可变参数及 defer - GO语言从入门到实战 函数是⼀等公⺠ 在Go语言中&#xff0c;函数可以分配给一个变量&#xff0c;可以作为函数的参数&#xff0c;也可以作为函数的返回值。这样的行为就可以理解为函数属于一等公民。 与其他主要编程语⾔…

Nodejs内置模块process

文章目录 内置模块process写在前面1. arch()2. cwd()3. argv4. memoryUsage()5. exit()6. kill()7. env【最常用】 内置模块process 写在前面 process是Nodejs操作当前进程和控制当前进程的API&#xff0c;并且是挂载到globalThis下面的全局API。 下面是process的一些常用AP…

linux开发板中的数据存储和读取操作

问题&#xff1a;MQTT远程下发的参数存储在本地linux开发板&#xff0c;开发板依据该参数执行相应功能&#xff0c;当开发板重新上电时依然能继续执行该功能 解决方式&#xff1a; 在linux板中写一个标识并存储为文件&#xff0c;依据读取的文件标识执行相应的功能 1)打开文…

【2023】M1/M2 Mac 导入Flac音频到Pr的终极解决方案

介绍 原作者链接&#xff1a;https://github.com/fnordware/AdobeOgg 很早之前就发现了这个插件&#xff0c;超级好用&#xff0c;在windows上完全没有问题&#xff0c;可惜移植到mac就不行了&#xff08;然后我给作者发了一个Issue&#xff0c;后来就有大佬把m1的编译出来了&…

Ai绘画描述词 关键词大全 真人美女 二次元卡通美女 国漫动漫效果

超好看的二次元动漫美少年 都是用Ai工具直接绘画生成出来的。 还有真人绘画&#xff0c;效果也很逼真 还有更多的场景效果 寂静天空素材 做抖音 短视频 精美的图片素材都是通过Ai绘画的 但是绘画需要关键词去描述场景&#xff0c;Ai才能自动根据场景描述词生成出来图片。 如何…

【Java学习之道】接口与抽象类

引言 现在我们来聊聊接口和抽象类。在Java中&#xff0c;接口和抽象类是实现OOP的重要工具&#xff0c;它们允许我们定义规范和行为&#xff0c;让代码更具灵活性和可扩展性。这一节&#xff0c;我们就来详细探讨一下这两个神奇的功能。 一、接口 接口是一个完全抽象的类&am…

【LeetCode高频SQL50题-基础版】打卡第6天:第31~35题

文章目录 【LeetCode高频SQL50题-基础版】打卡第6天&#xff1a;第31~35题⛅前言员工的直属部门&#x1f512;题目&#x1f511;题解 判断三角形&#x1f512;题目&#x1f511;题解 连续出现的数字&#x1f512;题目&#x1f511;题解 指定日期的产品价格&#x1f512;题目&am…

通讯网关软件021——利用CommGate X2OPC实现OPC客户端访问Modbus设备

本文介绍利用CommGate X2OPC实现OPC客户端连接Modbus设备。CommGate X2OPC是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;SCADA系统上位机、PLC、设备具备Modbus通讯接口&#xff0c;上位机…

工程物料管理信息化建设(十二)——关于工程物料管理系统最后的思考

目录 1 功能回顾1.1 MTO模块1.2 请购模块1.3 采购模块1.4 催交模块1.5 现场管理模块1.6 数据分析和看板模块1.7 其它模块 2 最后几个问题2.1 按管线发料和直接发料重叠2.2 YHA 材料编码的唯一性问题2.3 “合同量单-箱单-入库单” 数据映射 3 关于未来的思考3.1 三个专业之间的关…

单点接地、多点接地、混合接地

有三种基本的信号接地方式:浮地、单点接地、多点接地。 浮地&#xff1a;目的是使电路或设备与公共地线可能引起环流的公共导线隔离起来&#xff0c;浮地还使不同电位的电路之间配合变得容易。缺点&#xff1a;容易出现静电积累引起强烈的静电放电。折中方案&#xff1a;接入泄…