汉诺塔+汉诺四塔(C/C++)

news2024/11/13 22:26:15

目录

汉诺塔

1  简介

 2  代码思路

2.1  对于次数的理解

2.2  对于移动的理解

3  代码

4  加深理解

汉诺四塔

1  思路

 2  代码


汉诺塔

1  简介

        汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

        法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

        不管这个传说的可信度有多大,如果考虑一下把64片金片,由一根针上移到另一根针上,并且始终保持上小下大的顺序。这需要多少次移动呢?这里需要递归的方法。假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。此后不难证明f(n)=2^n-1。n=64时,

        假如每秒钟一次,共需多长时间呢?一个平年365天有31536000 秒,闰年366天有31622400秒,平均每年31556952秒,计算一下:

18446744073709551615秒

        这表明移完这些金片需要5845.54亿年以上,而地球存在至今不过45亿年,太阳系的预期寿命据说也就是数百亿年。真的过了5845.54亿年,不说太阳系和银河系,至少地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭。

图解:

 2  代码思路

2.1  对于次数的理解

当n=1时,把所有圆盘从A挪到另一个柱需要1次

当n=2时,相当于n=1的基础上再把一个圆盘放到A,那么把新圆盘放到原圆盘的下面需要2次,所以总共需要1+2=3次

当n=3时,相当于在n=2的基础上再把一个圆盘放到A,那么把新圆盘放到原所有圆盘的下面需要4次,所以总共需要1+2+4=7次

当n=4时,相当于在n=3的基础上再把一个圆盘放到A,那么把新圆盘放到原所有圆盘的下面需要8次,所以总共需要1+2+4+8=15次

如此循环,构成递归,递归边界是n=1

2.2  对于移动的理解

先将n-1个圆盘从A柱移动到B柱上,然后将A柱上最后一个圆盘移动到C柱上,最后再把B柱上的n-1个圆盘移动到C柱上。如下图所示:

当n=1时:
1.将A柱上最后一个圆盘移动到C柱上(A →C)

当n=2时:
1.将1个圆盘从A柱移动到B柱上,重复n=1时的步骤,只不过是将那1个圆盘(从A借助于B移动到C)改为(从A借助于C移动到B)
2.将A柱上最后一个圆盘移动到C柱上(A →C)
3.将B柱上的1个圆盘移动到C柱上。重复n=1时的步骤,只不过是将那个圆盘(从A借助于B移动到C)改为(从B借助于A移动到C)

当n=3时:
1.将2个圆盘从A柱移动到B柱上。重复n=2时的步骤,只不过是将那2个圆盘(从A借助于B移动到C)改为(从A借助于C移动到B)
2.将A柱上最后一个圆盘移动到C柱上(A →C)
3.将B柱上的2个圆盘移动到C柱上。重复n=2时的步骤,只不过是将那2个圆盘(从A借助于B移动到C)改为(从B借助于A移动到C)

当n=4时:
1.将3个圆盘从A柱移动到B柱上。重复n=3时的步骤,只不过是将那3个圆盘(从A借助于B移动到C)改为(从A借助于C移动到B)
2.将A柱上最后一个圆盘移动到C柱上(A →C)
3.将B柱上的3个圆盘移动到C柱上。重复n=3时的步骤,只不过是将那3个圆盘(从A借助于B移动到C)改为(从B借助于A移动到C)

当n时:

1.将n-1个圆盘从A柱移动到B柱上。重复n=n-1时的步骤,只不过是将那n-1个圆盘(从A借助于B移动到C)改为(从A借助于C移动到B)

2.将A柱上最后一个圆盘移动到C柱上(A →C)

3.将B柱上的n-1个圆盘移动到C柱上。重复n=n-1时的步骤,只不过是将那n-1个圆盘(从A借助于B移动到C)改为(从B借助于A移动到C)

如此可见:我们要明白圆盘具体是怎么移动的

3  代码

#include <bits/stdc++.h> 
using namespace std;
void move(char A, char C, int n)
{
 cout<<"把第"<<n<<"个圆盘从"<<A<<"--->"<<C<<endl;
}

void HanoiTower(char A, char B, char C, int n)
{
 if (n == 1)
 {
  move(A, C, n);
 }
 else
 {
  //将n-1个圆盘从A柱借助于C柱移动到B柱上
  HanoiTower(A, C, B, n - 1);
  //将A柱子最后一个圆盘移动到C柱上
  move(A, C, n);
  //将n-1个圆盘从B柱借助于A柱移动到C柱上
  HanoiTower(B, A, C, n - 1);
 }
}

int main()
{
 int n = 0;
 cout<<"输入A柱子上的圆盘个数:";
 cin>>n;
 //将n个圆盘从A柱借助于B柱移动到C柱上
 HanoiTower('A', 'B', 'C', n);
 return 0;
}

4  加深理解

【算法动画】汉诺塔_哔哩哔哩_bilibili汉诺塔是在讲解递归思想的时候常用的例子汉诺塔拥有三根柱子和N个大小不同的圆盘目标是把这N个圆盘从A柱移动到C柱,并且在移动过程中大的圆盘不能在小的圆盘上移动汉诺塔总共需要三步:1、将N-1个圆盘移动到B柱(这样就腾出了空间)2、将第N个圆盘移动到C柱3、再将N-1个圆盘移动到C柱这样就能完成目标那N-1个圆盘要怎么移动?只要继续采用上面三步就行了,只不过目的地不一样, 视频播放量 10649、弹幕量 3、点赞数 186、投硬币枚数 3、收藏人数 89、转发人数 14, 视频作者 Maple-Kaede, 作者简介 闲番鉴赏家,相关视频:两分钟(一句口诀)学会汉诺塔,天荒地老版64层汉诺塔,算法动画图解之递归汉诺塔 —— 一分钟让你明白汉诺塔和递归的原理,汉诺塔游戏(小学微课),寻路算法动画演示,8分钟讲懂一个算法,汉诺塔(栈与递归),数学日常5.数学老师的一句口诀教你通关汉诺塔,2分钟看完24种算法,【双语字幕】汉诺塔递归可视化https://www.bilibili.com/video/BV13q4y157CR/?buvid=XU0CC290F8EF93BE2CE1D4A2B2BC7EC47690A&is_story_h5=false&mid=llJNPRNvRR%2BH1p8%2FcpmuUA%3D%3D&p=1&plat_id=114&share_from=ugc&share_medium=android&share_plat=android&share_session_id=f72508a0-3722-4890-b9ef-8009addb2fd2&share_source=WEIXIN&share_tag=s_i×tamp=1675041598&unique_k=f8P62EW&up_id=430472716&vd_source=04b509237de6b311e334aa04cc4ce9c9

汉诺四塔

1  思路

1)、将A柱上n个盘子划分为上下两部分,下方部分共有k(1≤k≤n)个盘子,上方部分共有n - k个盘子。
2)、将A柱上面部分n–k个盘子经过C、D柱移至B柱。
3)、将A柱剩余的k个盘子经过C柱移至D柱。
4)、将B柱上的n–k个盘子经过A、C柱移至D柱。

也就是说第二步第四步我们使用汉诺四塔算法,而第三步我们使用汉诺三塔即可。

 2  代码

#include <bits/stdc++.h>
using namespace std;
int HanoiTower3(int n, char a, char b, char c) //a->c b做中间柱子 
{
	if (n == 1)
	{
		return 1;
	}
	int now = 0;
	now += HanoiTower3(n - 1, a, c, b);
	cout<<a<<"->"<<c<<endl;
	now++;
	now += HanoiTower3(n - 1, b, a, c);
	return now;
}
 
int HanoiTower4(int n, char a, char b, char c, char d)
{
	if (n == 1)
	{
		cout<<a<<"->"<<d<<endl;
		return 1;
	}
	int minans = 100000;
	for (int k = 1; k < n; k++)
	{
		int ans = 0;
		ans += HanoiTower4(n - k, a, c, d, b); //n-k指的是上面那部分,k指的是下面部分 
		ans += HanoiTower3(k, a, c, d);
		ans += HanoiTower4(n - k, b, a, c, d);
			minans = ans;
	}
	return minans;
}
 
int main() 
{
	int n;
	cin >> n;
	cout << HanoiTower4(n, 'A', 'B', 'C', 'D') << endl;
	return 0;
}

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

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

相关文章

关于e^x的部分公式和约算方法

常用的几个不等式: ex≥x1e^{x}\geq x1ex≥x1ln⁡x≤x−1\ln x\leq x-1lnx≤x−1ex≥exe^{x} \geq exex≥exex≥1xx22e^x\geq1x\frac{x^2}{2}ex≥1x2x2​ 当x>0时&#xff0c;ex≥ex(x−1)2x2−(e−2)x1e^x\geq ex(x-1)^{2}x^2-(e-2)x1ex≥ex(x−1)2x2−(e−2)x1 上述算式在…

数据库系统概论——函数依赖、码和范式(1NF、2NF、3NF、BCNF)详解

文章目录概念回顾1、函数依赖的定义1.1 平凡函数依赖和非平凡函数依赖1.2 完全函数依赖和部分函数依赖1.3 传递函数依赖2、码2.1 主码和候选码2.1主属性与非主属性2.2 全码2.3 外部码3、范式3.1 第一范式&#xff08;1NF&#xff09;3.2 第二范式&#xff08;2NF&#xff09;3.…

现在的互联网技术,已蜕变成区块链技术,人工智能技术

在互联网的进化过程中&#xff0c;我们看到了互联网技术的不断孪生与蝶变。现在的互联网技术&#xff0c;早已不再是传统意义上的互联网技术&#xff0c;而是蜕变成为了大数据技术&#xff0c;云计算技术&#xff0c;蜕变成为了区块链技术&#xff0c;人工智能技术。这些新的技…

【STM32笔记】HAL库ADC测量精度提高方案(利用内部参考电压VREFINT计算VDDA来提高精度)

【STM32笔记】HAL库ADC测量精度提高方案&#xff08;利用内部参考电压VREFINT计算VDDA来提高精度&#xff09; 多数STM32的MCU 都没有内部基准电压 如L496系列 但在外接VDDA时&#xff08;一般与VCC 3.3V连接&#xff09; 有可能VCC不稳定 导致参考电压不确定 从而使ADC测量不…

深度学习调参炼丹术(总结向)

调参控制变量&#xff0c;每次调一个值。 1.初始化方式&#xff1a;FC/CNN用kaiming uniform或normalize&#xff0c;Emendding选截断normalize 2.activation function&#xff1a;sigmoid(淘汰)、tanh(淘汰)、relu(推荐)、leakey-relu 3.优化器&#xff1a;SGD动量&#xff0…

若依配置教程(三)新建模块

若依模块化管理&#xff0c;使代码更加规范化&#xff0c;方便在不同文件夹下进行修改和开发。 接下来是新建模块的步骤&#xff1a; 文章目录**接下来是新建模块的步骤&#xff1a;**1.创建新的module2.配置pom.xml1.创建新的module 项目上鼠标右击&#xff1a; 然后修改项…

Kettle 实战教程

Kettle 实战教程1.引言....................................................................................81.1 编写目的...........................................................81.2 阅读对象...........................................................91.3 术…

DBCO-SS-Mal;DBCO二硫键-马来酰亚胺-点击化学

DBCO-SS-Maleimide&#xff1b;Mal-SS-DBCO 英 文 &#xff1a;DBCO-SS-Maleimide 中文&#xff1a;二苯并环辛炔-二硫键-马来酰亚胺 分子式&#xff1a;C30H30N4O5S2 分子量&#xff1a;590.71 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 用 途&#xff…

做自媒体,有哪些好用的工具和软件,这6大自媒体工具,力荐!

工具一&#xff1a;效率控 效率控是一个汇集很多工具的工具APP。使用它可以用来习惯养成&#xff0c;表情制作&#xff0c;二维码生成&#xff0c;倒数日&#xff0c;文字识别&#xff0c;配色方案等等。 它特别一个亮点的功能是剪切板增强&#xff0c;还有一个特别实用的功能是…

DevStyle,一个让Java开发更现代化的工具!

如果您喜欢Eclipse的强大功能&#xff0c;但对它的可用性和美观度没有很高的要求&#xff0c;那么从今天开始&#xff0c;请准备好从全新的角度来看待Eclipse。在之前暗黑的插件基础上&#xff0c;MyEclipse官方团队为大家带来了DevStyle。使用DevStyle&#xff0c;开发人员可以…

小程序提升篇-组件

提升篇学习目标如何自定义小程序组件小程序组件中behaviors的作用安装和配置vant-weapp组件库如何使用MobX实现全局数据共享如何对小程序API进行Promise化小程序组件学习目标创建并引用组件&#xff08;全局、局部、usingComponent&#xff09;修改组件样式&#xff08;option-…

Java JVM:字节码执行引擎(六)

执行引擎是 Java 虚拟机核心的组成部分之一&#xff0c;执行引擎由软件自行实现 目录一、运行时栈帧结构二、方法调用三、基于栈的字节码解释执行引擎四、OSGI&#xff1a;灵活的类加载器架构一、运行时栈帧结构 Java 虚拟机以方法作为最基本的执行单元&#xff0c;“栈帧”则…

如何用ffmpeg截取视频片段 以及 截取时间不准确的坑

之前在工作中&#xff0c;有遇到需要程序化截取视频片段的场景&#xff0c;这里使用ffmpeg命令行就可以很容易实现&#xff0c;这里也记录下我们使用过程中遇到的坑&#xff0c;希望对大家也有所帮助。    举个例子&#xff0c;当我们要截取视频文件中input.mp4的第15秒到第9…

【C语言练习】逻辑分析题

目录题目一&#xff1a;求名次题目详情&#xff1a;解题思路&#xff1a;题目二&#xff1a;找凶手题目详情&#xff1a;解题思路&#xff1a;题目一&#xff1a;求名次 题目详情&#xff1a; 5位运动员参加了10米台跳水比赛&#xff0c;有人让他们预测比赛结果&#xff1a; A…

(02)Cartographer源码无死角解析-(52) 2D点云扫描匹配→ceres扫描匹配:CeresScanMatcher2D→栅格地图残差

讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解(02)Cartographer源码无死角解析-链接如下: (02)Cartographer源码无死角解析- (00)目录_最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/127350885 文末…

上海洲邦携手图扑建设数字孪生工厂,获 2022 智能制造优秀场景

前言 12 月 2 日&#xff0c;工信部公示了 2022 年度智能制造示范工厂揭榜单位和优秀场景名单。图扑软件和上海洲邦合作建设的宁波甬友数字孪生工厂被评为优秀场景&#xff0c;全国共有 369 个智能制造典型场景入选。 《智能制造试点示范行动实施方案》包括智能制造优秀场景和…

ESP-IDF:快速排序测试

ESP-IDF:快速排序测试 /快速排序测试/ void printArray(int arr[], int len) { for (int i 0; i < len; i) { cout << arr[i] << " "; } cout << endl; } void QuickSort(int arr[], int start, int end) { int i start; int j end; // 找…

【IoT】蔽障智能车设计:带有无线调试系统的蔽障小车

说明 近年来随着计算机在社会领域的渗透和大规模集成电路的发展&#xff0c;单片机的应用正在不断地走向深入&#xff0c;由于它具有功能强&#xff0c;体积小&#xff0c;功耗低&#xff0c;价格便宜&#xff0c;工作可靠&#xff0c;使用方便等特点&#xff0c;因此越来越广…

Activiti7工作流-使用idea插件actiBPM设计请假流程---工作流工作笔记005

首先我们看一下我们之前写的测试类, ProcessEngine 这个流程引擎,打开 看源码可以看到有几个常用的, HistoryService就是用来管理之前_hi表的,关于历史的 TaskService用来管理任务的 RuntimeService用来管理_run那些运行时的表的 然后我们还可以通过,上面定义的processEngi…

程序员的成长离不开哪些软技能?

道破一个残忍的真相&#xff1a;一个程序员的成长往往是软技能&#xff1e;硬技能&#xff0c;想纯靠技术能力一路挺过35岁基本是不可能的任务&#xff0c;作为一个优秀的程序员&#xff0c;离不开以下这些软技能。 较真 所有在技术上的较真都是一次专业技能的提升&#xff0…