(一)、题目
汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有n层的时候,打印最优移动过程和最优移动总步数。
(二)、题目描述
(三)、样例
(四)、备注
(五)、程序代码(递归法)
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
int step = sort(n,"left","mid","right","left","right");
System.out.println("It will move "+step+" steps.");
}
public static int sort(int num,String left,String mid,String right,String from,String to) {
if(num < 0) {
return 0;
}
if(num == 1) {
if(from.equals("mid") || to.equals("mid")) {
System.out.println("Move "+ num + " from "+from+" to "+to);
return 1;
}else {
System.out.println("Move "+ num + " from "+from+" to "+mid);
System.out.println("Move "+ num + " from "+mid+" to "+to);
return 2;
}
}
if(from.equals("mid") || to.equals("mid")) {
String another = (from.equals("left") || to.equals("left"))?"right":left;
int part1 = sort(num-1,left,mid,right,from,another);
System.out.println("Move "+ num + " from "+from+" to "+mid);
int part2 = 1;
int part3 = sort(num-1,left,mid,right,another,mid);
return part1+part2+part3;
}else {
int part1 = sort(num-1,left,mid,right,from,to);
System.out.println("Move "+ num + " from "+from+" to "+mid);
int part2 = 1;
int part3 = sort(num-1,left,mid,right,to,from);
System.out.println("Move "+ num + " from "+mid+" to "+to);
int part4 = 1;
int part5 = sort(num-1,left,mid,right,from,to);
return part1+part2+part3+part4+part5;
}
}
}
(六)、代码思路(递归法)
- 我尝试了一下往代码里加入注释,感觉不太好解释,我也就不班门弄斧了,这里直接贴上书上的解释吧,这样大家更好理解。
- 其实上面的代码也就是分为两种情况。一种是想从“左”移动到“中”,另一种是从“左”移动到“右”
(七)、程序代码(非递归法)
import java.util.*;
public class Main {
static Stack<Integer> ls = new Stack<Integer>();
static Stack<Integer> ms = new Stack<Integer>();
static Stack<Integer> rs = new Stack<Integer>();
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
int step = sort(n);
System.out.println("It will move "+step+" steps.");
}
public static int sort(int num) {
ls.push(Integer.MAX_VALUE);
ms.push(Integer.MAX_VALUE);
rs.push(Integer.MAX_VALUE);
for(int i = num; i > 0; i--) {
ls.push(i);
}
int step = 0;
Action[] record = {Action.No};
while(rs.size()!= num+1) {
step += process(record,Action.ltom,Action.mtol,ls,ms,"left","mid");
step += process(record,Action.mtol,Action.ltom,ms,ls,"mid","left");
step += process(record,Action.rtom,Action.mtor,rs,ms,"right","mid");
step += process(record,Action.mtor,Action.rtom,ms,rs,"mid","right");
}
return step;
}
public static int process(Action[] record,Action pre,Action now,Stack<Integer> s1,Stack<Integer> s2,String from,String to) {
if(record[0] != pre && s1.peek() < s2.peek()) {
s2.push(s1.pop());
System.out.println("Move "+ s2.peek() + " from "+from+" to "+to);
record[0] = now;
return 1;
}
return 0;
}
}
enum Action {
No,ltom,mtol,rtom,mtor
}
(八)、代码思路(非递归法)