新规则:限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有N层的时候,打印最优移动过程和最优移动步数;
public class hanoiProblem1 {
public static void main(String[] args) {
hanoi(2,"left","mid","right");
}
public static int hanoi(int num,String left,String mid,String right){
if(num<1){
return 0;
}
return process(num,left,mid,right,left,right);
}
public static int process(int num,String left,String mid,String right,String from,String to){
//如果只有一个盘子
if(num==1){
//并且其中一个端点是中间的情况 只需走一步
if(from.equals(mid) || to.equals(mid)){
System.out.println("Move 1 from"+from+" to "+to);
return 1;
}else{
//不过中点 需要走两步
System.out.println("Move 1 from"+from+" to "+mid);
System.out.println("Move 1 from"+ mid+" to "+to);
return 2;
}
}
//n个盘子的时候
//并且其中一个端点在中间的情况 有三大步骤
if(from.equals(mid) || to.equals(mid)){
//another表示左端或者右端 来保证定有从左到右
String another = (from.contentEquals(left)||to.equals(left))?right:left;
//part1指n-1从左到右走的步数
int part1 = process(num-1,left,mid,right,from,another);//n-1从左到中(或者从右到中)
//part2指n号盘走的一步
int part2 = 1;
System.out.println("Move"+num+" from "+from+" to "+to);
int part3 = process(num-1,left,mid,right,another,to);//n盘移动到中间后 n-1重新返回中
return part1+part2+part3; // 返回所有的步数
}else{
//其中没有端点在中点上,即要么从左到右 要么从右到左
int part1 = process(num-1,left,mid,right,from,to);//n-1从左到右
int part2 = 1;//底盘从左到中间
System.out.println("Move"+num+" from "+from+" to "+mid);
int part3 = process(num-1,left,mid,right,to,from);//n-1从右回到左边
int part4 = 1;//底盘从中间走到右盘
System.out.println("Move"+num+" from "+mid+" to "+to);
int part5 = process(num-1,left,mid,right,from,to);//n-1从左边再到右边
return part1+part2+part3+part4+part5;
}
}
}
测试结果: