求解汉诺塔的移动次数和步骤
一、问题重述
有三根柱子和个大小不同的盘子,开始时,所有盘子以塔状叠放在A柱子上,将A柱子上的盘子移动到B柱子上,借助C柱子作为 缓冲。移动规则如下:
(1)一次只能移动一个盘子;
(2)任何时候不能把盘子放在比它小的盘子上面;
二、提出问题
1.从一根柱子移动n个盘子到另一根需要多少次?
2.从一根柱子移动n个盘子到另一根步骤又是怎样的?
三、问题分析
假设移动次数函数为F(n);
问题1:
1)对于问题一,假设需求吧盘子从A移到B,当移动一个盘子时直接从A移到B,看成F(1)=1;
2)当移动两个盘子时,先将最上面的一个盘子移动到C,在把最下面的盘子移动到B;然后将C上的盘子移到B,这时候最上面的一个盘子移动两次,一次移到C,然后又从C
移到B,看成F(2)=F(1)+2*F(1)。
3)当移动三个的时候,先将最上面两个借助B移动到C,然后将最下面一个大盘子直接由A移到B,接着在C上的两个盘子借助A移到B;总结为移动一次一个盘子,移动两次两
个盘子,表示为:F(3)=F(1)+2*F(2);
4)以此类推得到递归函数:移动n个盘子时,先将最上面的n-1个盘子移到C,在把最下面的一个直接移到B,然后把C上的盘子移到B,表示为F(n)=F(1)+F(n-1);
import java.util.Scanner;
public class Main{
public static void main(String []arg){
Scanner cin=new Scanner(System.in);
while(cin.hasNext()){
int n=cin.nextInt();
System.out.println(hanoi(n));
}
cin.close();
}
private static int hanoi(int n) {
if(n==1)
return 1;
else
return 2*hanoi(n-1)+1;
}
}
讨论完问题一再来讨论升级版的汉诺塔吧!!!!!
问题二:
对于问题2了,其实思路和问题一有点相似之处,用伪代码来展示一下思路吧:
hanoi(移动盘子数n,从A移动到B,缓冲柱C){
if(n==1)
直接从A移到B;
else{
hanoi(移动n-1个盘子,从A移动到C,缓冲柱B);
在移动第n个盘子从A到B;
hanoi(再移动C上的n-1个盘子,从C移到B,缓冲柱A);
}
}
这样分析应该比较容易懂吧!接下来就是源代码了:
import java.util.Scanner;
public class Main{
public static void main(String []arg){
Scanner cin=new Scanner(System.in);
int n=cin.nextInt();
hanoi(n,'A','B','C');
cin.close();
}
private static void hanoi(int n, char A, char B, char C) {
if(n==1)
System.out.println(A+"-->"+B);
else{
hanoi(n-1,A,C,B);
System.out.println(A+"-->"+B);
hanoi(n-1,C,B,A);
}
}
}
当然除了上述两种类型的汉诺塔问题之外还有其他改版的汉诺塔问题,比如说一次允许移动若干个等等,小编就不一一讲解了,因为最终换化的思路还是变成上述那样的!!!