汉诺塔问题

汉诺塔问题问题描述:
有A,B,C三根柱子,A上有一叠自上到下是从小到大的盘子,需要将其全部移到C上,要求每次只能移一个盘子,且规定大盘子要在小盘子下面,问当有N个盘子的时候,最少移动多少次?

刚开始一直不知道N>=3的时候为什么是那样移,别人写的递归方程为什么那样写?看了好多博文加上自己的思路才明白!

首先我们要明白,A最下面最大的盘子一定要移到C柱子最底下!然后我们再来讨论:
当N=1时,很简单,直接从A->C;
当N=2时,A->B,A->C(A最大的盘子移到C),B->C,OK!
当N=3时,我们将三个盘子的上面两个捆绑,就又相当于是N=2的情况;
将捆绑的两个盘子从A移到B,再将底下最大的盘子从A移到C,再将捆绑的两个盘子从B移至C,OK!

然后我们考虑的问题就是上面两个捆绑的盘子是怎么A->B,历史总是惊人的相似!此时我们会发现这是的B充当着当N=2时C的角色,所以我们很容易推出应该是A->C,A->B,C->B;同理,两个捆绑的盘子是怎么B->C,不过是将(N=2时的情况)A换成B,于是B->A,B->C,A->C;

综上,N=3时,盘子应该这样移:A->C,A->B,C->B,A->C(最大的盘子从A移到C),B->A,B->C,A->C,一共移7次;

。。。以此类推,我们解决汉诺塔问题就要分三步骤:
1.将A上面n-1个盘子移到B;
2.将A底下最大的盘子移到C;
3.将B上n-1个盘子移到C;大功告成

用递归解决这个问题,代码如下:

#include<iostream>

using namespace std;

void move(char x,char z){
    cout<<x<<" "<<"to"<<" "<<z<<endl;	
} 

void hannot(int n,char x,char y,char z){//n指A柱子上的盘子总数,x,y,z指三个柱子
    if(n==1){
    	 move(x,z);
	} 
	else{
		hannot(n-1,x,z,y);  //表示盘子从A移到B 
		move(x,z);     //表示最大盘子从A移到C 
		hannot(n-1,y,x,z);   //表示盘子从B移到C
	}
}
int main(){
	int n;
	cin>>n;
	hannot(n,'A','B','C');
	return 0;
} 

感觉看递归代码,绕进去很难出来,但还是要掌握什么时候可以使用它解决问题:确定问题的结束条件以及如何让问题规模缩小。

欢迎大家批评指正拓展!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值