汉诺塔问题

题目: 

A、B、C 三个桌子,其中A桌子上放了几个大小不同的盘子,盘子的排列顺序为: 从上到下,依次从小到大递增;现要求把这些盘子从 A 桌子上移动到 C 桌子上,盘子移动时有一点要求:每次移动必须保证三张桌子上大盘子在下、小盘子在上。实现函数打印最优移动轨迹

举例说明:
(1) A 上一张 盘子时

移动顺序: A -> C

(2)A上有两张盘子时:

移动顺序: A->B

B->C

C->A

递归分析:

子问题:

步骤1:将圆盘1~n-1从A移动到B

步骤2:单独把圆盘n从from移动到to

步骤3:把圆盘1~n-1从B移动到C

结束条件:

圆盘只有1个,直接把这个圆盘从A移动到C即可


代码如下:

void Hanoi(int n)
{
	void Process(int n, char from, char mid, char to);
	if (n <= 0)
		return;
	Process(n, 'A', 'B', 'C');
}


void Process(int n, char from, char mid, char to)
{
	if (n == 1)
	{
		cout << from << "->" << to<<endl;
	}
	else
	{
		Process(n - 1, from, to, mid);
		Process(1, from, mid, to);
		Process(n - 1, mid, from, to);
	}
}

思考

为什么可以打印出所有的步骤,不是只是打印出来了只有一个即n==1的情况吗?

因为只有一个的情况,不只是从A移动到C,还有其他的,其他的路径也要打印出来


移动的最少步骤数

(1)首先求都在A上的圆盘1~n,,如果都移动到C上的最小步骤数,假设为S(n)

(2)根据上面的步骤,S(n)=步骤1的步骤总数+1+步骤3的步骤总数=S(n-1)+1+S(n-1)

(3)由S(1)=1,和S(n)+1=2(S(n-1)+1),根据等比数列求和公式可以求出S(n)=2^n-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值