小知识系列(3):Hanoi塔(汉诺塔,河内塔)

同样,借此来强化学习,但是说实话我写这个感觉很玄。Hanoi塔是昨天刚学到的东西,想了很久,感觉还是没有悟透,可能学到更多新东西,或产生了新的想法,或突然悟到了什么,届时会再做修改。
看了很多关于Hanoi塔的博客,说实话都是一头雾水,可能也是因为鄙人的理解能力有欠缺。一直看到一位博主的一篇讲解才略有启发,博客↓↓↓
传送门

(后续)
发现一位B站UP主的讲解更加细致,留下链接:↓↓↓
传送门

OK,言归正传。
Hanoi塔起源是什么?我们不多说,有兴趣的可以查一下。

Hanoi塔的规则是什么?

有三根柱子,将A柱子上所有的圆盘转移到C柱子。
1.在小圆盘上不能放大圆盘。
2.在三根柱子之间一回只能移动一个圆盘。
3.只能移动在最顶端的圆盘。

具体操作?

我们从最简单的开始:
一个盘:A→C;
两个盘:A→B,A→C,B→C;
三个盘:A->C , A->B , C->B , A->C , B->A , B->C , A->C

一个盘的时候,直接由A柱到C柱
两个盘的时候,把不是最大的一个放到B柱,然后把最大的从A放到C柱,再把B柱上的小盘放到C柱
三个盘的时候,步骤相同其实,就是把不是最大的放到B柱然后把最大的放到C柱,再借助A柱重复做一次两个盘的情况的步骤(其实就是重复两次)。

我们要解决n层Hanoi塔就要解决n-1层Hanoi塔,
我们要解决n-1层Hanoi塔就要解决n-2层Hanoi塔,
……
……
我们要解决3层Hanoi塔就要解决2层Hanoi塔,
我们要解决2层Hanoi塔就要解决1层Hanoi塔,
(分治思想)

总结一下:
只需要两步来解决这个问题:
第一步:
把n-1个小盘,从A柱移动到B柱,
把第n个小盘,由A柱移动到C柱。
第二步:
把n-1个小盘,从B柱移动到C柱。←其实这一步就是换位置后重复第一步。

接下来做题有疑问 可以返回这里查看。

在这里我先放上一道题以及完整的代码:

Description:

如图所示的三根针,其中A针上穿好了由大到小的64片金片,不论白天黑夜,总有一个和尚在按照下面的法则移动金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。和尚们预言,当所有的金片都从A针移到C针上时,世界就将在一声霹雳中消失,这就是所谓的汉诺塔。请编程求出将A针上所有金片移到C上的步骤。
在这里插入图片描述

Input

标准输入,一个整数N,表示有N个金片。

Output

标准输出,输出所有步骤,每一步骤占一行。

Input Copy
3
Output
A->C
A->B
C->B
A->C
B->A
B->C
A->C

完整代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
void f(int n,char a,char b,char c)
{
	if(n==1)
		cout<<a<<"->"<<c<<endl;
	else
	{
		f(n-1,a,c,b);
		cout<<a<<"->"<<c<<endl;
		f(n-1,b,a,c);
	}
}
int main()
{
	int n;
	cin>>n;
	f(n,'A','B','C'); 
	return 0;
}

我们要理解一个问题f()函数的4个位置分别的什么意思?
例如f(n,‘A’,‘B’,‘C’)
这里我们不是按照顺序分析:
第二个位置,就是起始位置位置1),也就是,你要把小盘从哪个柱子上拿走。
第四个位置,就是目标位置位置3),也就是,你要把小盘全都按照顺序放到这跟柱子上。
第三个位置,就是中转位置位置2),也就是,你要把最大的盘子,畅通无阻的从起始位置放到目标位置,其他的n-1个盘子必须放在这根柱子上。
第一个位置,就是我要转移小盘的数量。

可能发现了,我又写出位置1,位置2,位置3,为什么呢?
这是为了不让我们搞混与ABC搞混,ABC只是柱子的编号。
我们逐步分析,首先看main函数:

int main()
{
	int n;
	cin>>n;
	f(n,'A','B','C'); 
	return 0;
}

什么意思?根据之前说过的,我们可以知道,**就是把n个小盘,由A柱经B柱中转放到C柱上。**这也就是我们的目标。

再来看函数部分

void f(int n,char a,char b,char c)
{
	if(n==1)
		cout<<a<<"->"<<c<<endl;
	else
	{
		f(n-1,a,c,b);
		cout<<a<<"->"<<c<<endl;
		f(n-1,b,a,c);
	}
}

当只有一个盘子的时候,只要把A的盘子放到B即可。
如果大于1个,那么f(n-1,a,c,b)先把n-1个小盘,由A经过C的中转放到B。
然后再把第n个由A放到B
然后再把剩下的n-1个小盘由B经过A的中转放到C
(步骤最开始有提到过)

TIP

1.理解过程,分治的思想,把一个大问题分成若干个小问题,如果你试图自己置身于一个递归,我想不是天赋异禀,的确不一定能看的透……
在这里插入图片描述
所以你只要告诉他什么情况该做什么就好了,有些东西是一般人做不来的……比如鄙人……。整体考虑!整体考虑!整体考虑!

以上只是鄙人的拙见,如有不足之处,敬请斧正,如有难以理解的地方,亦可以指出。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值