关于汉诺塔问题

首先,我们要了解什么是汉诺塔问题。

汉诺塔问题源于古印度的一种游戏,而这种游戏是指在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。而我们游戏的目标则是:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。

操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

如图所示:

64个金盘数量太多,我们可以先从1个金盘开始研究。

如果A柱上只有一个金盘,那我们的移动顺序应该是:A ——> C。移动了1次。

如果A柱上有两个金盘,我们的移动顺序是:A ——>B , A ——>C , B——>C。移动了3次。

如果A柱上有三个金盘,我们的移动顺序是:A——>C , A——>B , C——>B , A——>C , B——>A , B——>C , A——>C。移动了7次。

由此我们可以得知,如果存在64个盘子,我们需要移动的次数是2的64次方减1。这是一个极大的数字,同时使用计算机计算也是占据了极大的时间。所以,研究这个问题,我们可以采取,递归的方法。

如果存在n个金盘,那么,存在的普遍规律是:要先将n-1个金盘放在B上面,再将最后一个金盘放在C上面

如果n==1,那么这个金盘就直接放到C柱上面。如果n!=1,那么将这些!=1的金盘先转移到B柱上面去。

所以存在以下代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//汉诺塔问题
//pos1:起始位置
//pos2:中转位置
//pos3:目的位置
//n:盘子的个数
void move(char pos1, char pos2)
{
	printf("%c—>%c  ", pos1, pos2);//打印盘子的移动方式

}
void Hannouta(int n, char pos1, char pos2, char pos3)
{
	if (n == 1)
	{
		move(pos1, pos3);
	}
	else
	{
		Hannouta(n - 1, pos1, pos3,pos2);
		move(pos1, pos3);
		Hannouta(n - 1, pos2, pos1, pos3);
	}
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	Hannouta(n, 'A', 'B', 'C');
	printf("\n");
	return 0;
}

其中,Hannouta是汉诺塔问题的解决函数,move是打印汉诺塔问题中盘子的移动方式的函数。

在代码中 pos1代表起始位置 pos2代表中转位置 pos3代表目的位置  n则是盘子的个数。

在Hannouta函数中,我们首先判断盘子的个数是不是1,如果是1直接调用move函数,将其从A柱(pos1)转移到C柱(pos3)。如果,盘子的个数不是1,那么将其n-1个盘子再进行Hannouta函数(进行递归),同时,将这n-1个盘子从A柱(pos1)通过C柱(pos3)转移到中转柱B柱(pos2)上去。将这n-1个盘子转移完后,if语句成立执行move(pos1,pos3),执行完这段语句后,根据递归再开始执行else中的语句。

从而达成汉诺塔游戏的目的。

(以上内容基于本人自己的理解,若有看不懂的地方可以私信联系,本人将尽其所能的为各位读者讲解)

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sunlightʊə

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值