题目链接: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;
}