汉诺塔问题详解

 汉诺塔(Hanoi Tower),又称河内塔,传说大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?

需要求两个问题,一是求所需要的步数,二是求移动过程中每一步的做法步骤

汉诺塔问题-步数

关于步数  是个很简单的问题  高中大家都学过  可能也做过类似的题

如果a上有n个盘子  要借助b柱子将他们移动到c上  那么  我们设总共需要移动步数为F(n)

那么 我们先将 最上面的n-1个盘子   借助c柱子移动到b上  毫无疑问需要步数  F(n-1)

那么 我们再把a上剩下的一个盘子  移动到c上 需要一步  然后再把b上的n-1个借助a移动到c上  需要F(n-1)

到这就完成了所有的移动  总共步数F(n)=2*F(n-1)+1

n=1的时候需要一步  所以 n就需要 2的n次方再减1

#include<stdio.h>
#include<math.h>
int main(){
    int n;
    scanf("%d",&n);
    printf("%d",(int)pow(2,n)-1);
    return 0;
}

这里要注意范围  如果n比较大的话可以用long long,时间上可以用快速幂优化

汉诺塔问题-步骤

关于 步骤,同样的递归思想

我们假设 函数  hanoi ( a , b , c , n )代表  把a上的n个盘子借助b移动到c的步骤

那么  如果n==1  则步骤就是  a->c  一步就好了

n不等于1 的时候  我们先把a上n-1个盘子借助c移动到b上  就是 hanoi ( a , c , b , n-1 )

再把a上最后一个挪到c     a->c

最后再把 b上n-1个盘子借助a挪到c上  hanoi ( b , a , c , n-1 )

整个过程就完成了   主要是要理解递归的思想  理解了思想  递归的程序写起来是最简单的

代码

#include<stdio.h>
void hanoi(char a,char b,char c,int n){
    if(n==1){
        printf("%c->%c ",a,c);
    }
    else{
        hanoi(a,c,b,n-1);
        printf("%c->%c ",a,c);
        hanoi(b,a,c,n-1);
    }
    return ;
}
int main(){
    int n;
    scanf("%d",&n);
    hanoi('A','B','C',n);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/holly_Z_P_F/article/details/81840786