题目描述
汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有n层的时候,打印最优移动过程和最优移动总步数。
输入描述:
输入一个数n,表示塔层数
输出描述:
按样例格式输出最优移动过程和最优移动总步数
示例1
输入
2
输出
Move 1 from left to mid
Move 1 from mid to right
Move 2 from left to mid
Move 1 from right to mid
Move 1 from mid to left
Move 2 from mid to right
Move 1 from left to mid
Move 1 from mid to right
It will move 8 steps.
说明
解法一:递归
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine().trim());
int res = H(num,"left","right","mid");
System.out.println("It will move "+res+" steps.");
}
public static int H(int n,String from,String to,String mid){
if(n==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;
}
}
if(from.equals("mid")||to.equals("mid")){
int p1 = H(n-1,from,mid,to);
System.out.println("Move "+n+" from "+from+" to "+to);
int p2 = H(n-1,mid,to,from);
return p1+1+p2;
}else{
int p1 = H(n-1,from,to,mid);
System.out.println("Move "+n+" from "+from+" to "+mid);
int p2 = H(n-1,to,from,mid);
System.out.println("Move "+n+" from "+mid+" to "+to);
int p3 = H(n-1,from,to,mid);
return p1+p2+p3+2;
}
}
}
解法二:非递归
import java.io.*;
import java.util.*;
public class Main{
public static Action record = Action.no;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine().trim());
int res = H(num,"left","right","mid");
System.out.println("It will move "+res+" steps.");
}
public static int H(int n,String left,String right,String mid){
Stack<Integer> l = new Stack<>();
Stack<Integer> m = new Stack<>();
Stack<Integer> r = new Stack<>();
l.push(Integer.MAX_VALUE);
m.push(Integer.MAX_VALUE);
r.push(Integer.MAX_VALUE);
for(int i=n;i>0;i--){
l.push(i);
}
int step = 0;
while(r.size()!=n+1){
//只有一个能执行
step += fsTots(Action.mtr,Action.rtm,r,m,right,mid);
step += fsTots(Action.rtm,Action.mtr,m,r,mid,right);
step += fsTots(Action.mtl,Action.ltm,l,m,left,mid);
step += fsTots(Action.ltm,Action.mtl,m,l,mid,left);
}
return step;
}
public static int fsTots(Action preno,Action now,Stack<Integer> fs,Stack<Integer> ts,String from,String to){
if(record!=preno&&fs.peek()<ts.peek()){
record = now;
ts.push(fs.pop());
System.out.println("Move "+ts.peek()+" from "+from+" to "+to);
return 1;
}
return 0;
}
enum Action{
no,ltm,mtl,rtm,mtr
}
}