简单的汉诺塔问题【递归】

题目链接:http://bailian.openjudge.cn/practice/4147/

问题描述:

有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆: 每次只能移动一个圆盘; 大盘不能叠在小盘上面。 提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。

问:如何移?最少要移动多少次?

汉诺塔示意图如下:

三个盘的移动:

输入:

输入为一个整数后面跟三个单字符字符串。
整数为盘子的数目,后三个字符表示三个杆子的编号。

输出:

扫描二维码关注公众号,回复: 4218806 查看本文章

输出每一步移动盘子的记录。一次移动一行。
每次移动的记录为例如3:a->b 的形式,即把编号为3的盘子从a杆移至b杆。
我们约定圆盘从小到大编号为1, 2, ...n。即最上面那个最小的圆盘编号为1,最下面最大的圆盘编号为n。

样例输入:

3 a b c

样例输出:

1:a->c
2:a->b
1:c->b
3:a->c
1:b->a
2:b->c
1:a->c

解题思路:

 把前n-1个盘放到B杆上,再把第n个盘放到第C个杆上,最后把前n-1个盘放到第C个杆上,即可完成任务。

那么如何把前n-1个盘放到B杆上呢?

我们可以通过C杆,将前n-2个盘放到C杆上,再把第n-1个盘放到B杆上,最后把前n-2个盘放到B杆上。

以此类推对前n-3、n-4、n-5 ··· 个盘的操作,当只剩一个盘时,直接将盘放到该放的杆上即可。

代码如下:

#include <iostream>
#include <cstdlib>
using namespace std;
void rec(int n,int base,char t1,char t2,char t3)	// 此次要移动多少个盘;最底层盘的编号;所在杆、中转杆、目的杆
{
	if(n == 1) {	// 只需一动一个盘子
		cout << base << ":" << t1 << "->" << t3 <<endl;	// 将盘从t1直接放到t3  
		return;		// 递归终止
	}

	rec(n-1,base-1,t1,t3,t2);	// 将前n-1个盘放到t2

	cout << base << ":" << t1 << "->" << t3 << endl;	// 直接将第n个盘放到t3

	rec(n-1,base-1,t2,t1,t3);	// 最后将前n-1个盘放到t3
}
int main()
{
	int num;	// 所需移动的盘数
	char tower1,tower2,tower3;	// 所在杆、中转杆、目的杆

	cin >> num >> tower1 >> tower2 >>tower3;

	rec(num,num,tower1,tower2,tower3);	  

	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42765557/article/details/84304482
今日推荐