T00003 Hanoi塔问题

2017.09.28

题目描述:

某一天茂青正在网络中心值班,正当无聊之际,陈曦经过网络中心并给了茂青一个汉诺塔以来解闷。汉诺塔的规则如下:
假定有三根柱子,从左到右称为A柱、B柱、C柱,A柱上有n个从上到下尺寸依次增大的盘子,现在要将A柱上的n个盘子以同样的次序移到C柱,移动的规则为:小的盘子不能在大的盘子的下面,每次移动只能移动一个盘子。
茂青有点懵,突然间他看到了旁边的计算机,决定写一个程序来输出n个盘子汉诺塔的解决步骤。
(以1标记最小的盘子,2标记第二小的盘子,以此类推。)

输出:

为解决汉诺塔问题的最少步骤

输入:

一个数字n,n为汉诺塔A柱上的盘子数量

数据要求:

对于100%的数据来说,1≤n≤10

输入示例:

3

输出示例:

Move 1 From A To C
Move 2 From A To B
Move 1 From C To B
Move 3 From A To C
Move 1 From B To A
Move 2 From B To C
Move 1 From A To C

时间限制:

2s

内存限制:

128000KB

题目分析:

这道题是一道非常经典的算法题目,考察的是最基本的递归算法。解决Hanoi塔问题的最常用思想是,将A塔的n-1个盘子移动到B塔,然后将A塔最后一个大盘子移动到C塔,再将B塔的n-1个盘子通过A塔移动到C塔,从而完成n个盘子A塔到C塔的转移。
那每次只能移动一个盘子啊,那我怎么同时移动n-1个盘子呢?
那就需要对这个移动盘子的方法缩小规模了。
我要移动A塔的n-1个盘子到B塔,那我就需要将上面n-2个盘子移动到B塔,再将第1个盘子搭在B塔的n-2个盘子的上面。
那我要怎么移动n-2个盘子呢,照例,将上面n-3个盘子移动到B塔,直到n-j=1为止。(中转塔是某个空着的柱子)
那以n=3为例:
根据上述思路,我要将第1、2两个盘子从A塔移动到B塔。
要移动这2个盘子从A塔到B塔,需要将第1个盘子移到C塔,将第2个盘子移到B塔,再将第1个盘子移到B塔。
那么问题解决方案就一目了然了。
代码贴上:

#include <iostream>
using namespace std;
void Hanoi(int m, char a, char b, char c)//此处的a为起始柱,b为中转柱(即为空柱),c为目标柱
{
    if (m == 1)
    {
        cout << "Move " << m << " From " << a << " To " << c<<endl;//将仅剩的一个盘子从A柱移到C柱
    }
    else
    {
        Hanoi(m - 1, a, c, b);//将m-1个盘子A柱移到B柱,以C为中转柱
        cout << "Move " << m << " From " << a << " To " << c<<endl;
        Hanoi(m - 1, b, a, c);//m-1个盘子从B柱移到C柱,以A为中转柱
    }
}
int main()
{
    int n;
    cin >> n;
    Hanoi(n, 'A', 'B', 'C');

    return 0;
}

如果还是对这个问题难以理解的,其主要原因是因为大脑的堆栈没有那么大,难以模拟发生的事情。大家可以在脑子里从n=1,2,3这样的基本情况入手,推出一般解法。

猜你喜欢

转载自blog.csdn.net/weixin_40427089/article/details/78122548