汉诺塔(小和尚串串子)

 游戏介绍


汉诺塔这个游戏我想我们在很小的时候就玩过吧,从前,寺庙里有个贪玩的小和尚,老是在院子里打扰师兄们清修,住持为了惩罚小和尚,就跟他说,院子里有三个柱子,分别为A柱,B柱和C柱,A柱上有64 个盘子,游戏规则是小和尚在一次只允许挪一个盘子的前提下,将A柱上的盘子借助B柱挪到C柱上,而且保证下面的盘子一定要比上面的大,聪明的小和尚,能完成这项任务吗?需要多长时间呢


# 游戏分析

突然有这么多盘子在A柱上,我们好像无从下手,我们可以先不考虑这么多盘子 假设A柱上只有一个盘子,我们是不是很容易就能想到 直接从A挪到C啊即A ->C 如下图所示:

 当有两个盘子的时候,我们是不是先把A上面的第一个盘子先挪到B柱上,再把A柱子上的最后一个挪到C柱上,然后再把B柱上的挪到C柱上,即 A->B,A->C,B->C 如下图所示:

 当有三个盘子的时候呢,那就是A->C,A->B,C->B,A->C,B->A,B->C,A-C

那当A柱上有四个盘子呢,我们不能在这么傻呵呵的这么一点点挪了,我们得分析我们前三次挪的规律了啊

当有一个盘子的时候,我们是把A->C,

当有两个盘子的时候 我们是把A柱第一个盘子挪到B然后再把A柱最下面一个挪到C上,A->B,A->C,B->C。

当有三个的时候,A->C,A->B,C->B,A->C,B->A,B->C,A-C。
我们是把A盘上除了最底下一个盘子的其余两个盘子当成一个整体挪到B盘上,然后把最底下一个挪到C盘上,这样,再考虑B柱上的两个,再把B柱上第一个当成整体,又重新开始,把B盘上除了最底下一个的剩余的一个盘子挪到A柱上,然后,把B柱最底下一个挪到C柱上,我们有没有发现这其实就是一个递归啊。当有A柱上有n个盘子,那我们就把 n-1个当成整体,反复去递减重复同步骤的挪。为了方便大家理解,我把最精华的步骤用图来表示。

当c柱上已经有最大的一个盘子 在上面的时候,我们就可以不用考虑它的存在,那其实场内柱子上就变成了三个盘子在移动,我们要想把B柱上的三个挪到C上,其实还是同一种思想,把B柱子上前两个盘子先挪到A柱子上,把B柱最底下的盘子挪到C上,挪完就又可以少考虑一个盘子的存在,柱子上就变成两个盘子在移动了,如此反复递归,直到剩下一个盘子。


# 代码实现

#include<stdio.h>


// 移动函数
//一次只能移动一个盘子
void move(char post1, char post2)
{
	printf("%c -> %c",post1,post2);
}
//开始实现
// n 是要放的盘子个数
// post1 是原地址
// post2 是中转地址
// post3 是目的地址

void hanoi(int n,char post1,char post2,char post3)
{
	if (n == 1) // 递归的限制条件(直到场内柱子上只有一个盘子,否则一直递归)
	{
		move(post1, post3);//当只有一个盘子的时候,就只诺一次

	}
	else
	{
		hanoi(n - 1,post1,post3,post2);//把n-1个盘子 通过C盘挪到B盘
		move(post1, post3);//把A柱最底下的盘子挪到C柱
		hanoi(n - 1, post2, post1, post3);//n -1个在B柱上我们要通过A柱转义到C柱

	}

}
int main()
{
	hanoi(1,'A','B','C');
	printf("\n");
	hanoi(2, 'A', 'B', 'C');
	printf("\n");
	hanoi(3, 'A', 'B', 'C');
	printf("\n");


	return  0;
}

结果对比:

 

我们之前分析的:

 

 

 结尾:假设小和尚挪一步的话需要一秒的话,他得需要2^64 -1秒,转换成年的话,是多少年呢,大家可以试一下啊

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值