限制不能从最左侧的塔直接移到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有N层的时候,打印最优移动过程和最优移动总步数。
方法一:
递归
分析:如果剩下N层塔,从最上到最下依次为1~N,则:
1.如果剩下的N层塔都在“左”,希望全部移到中,则有三步:
(1)将1~N-1层塔先全部从左移到右。(递归)
(2)将第N层塔从左移到中
(3)将1~N-1层塔全部从右移到中(递归)
注:如果剩下的N层塔从中移到左,从中移到右,从右移到中,过程与上述一样。
2.如果剩下的N层塔都在“左”,希望全部移到右
(1)将1~N-1层塔先全部从左移到右。(递归)
(2)将第N层塔从左移到中
(3)将1~N-1层塔全部从右移到左。(递归)
(4)将第N层塔从中移到右
(5)将1~N-1层塔全部从左移到右。(递归)
代码如下:
import java.util.Scanner;
public class hannuo {
public int process(int n,String left,String mid,String right,String from,String to){
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 "+from+ " to "+to);
return 2;
}
}
int result=0;
if(from.equals(mid)||to.equals(mid)) {
String temp = (from.equals(left) || to.equals(right)) ? right : left;
int step1 = process(n - 1, left, mid, right, from, temp); //递归
int step2 = 1;
System.out.println("Move" + n + "from" + from + " to " + to);
int step3 = process(n - 1, left, mid, right, temp, to);
result=step1+step2+step3;
System.out.println("移动总步数"+ result);
}
else{
int step1 = process(n - 1, left, mid, right, from, to); //递归
int step2 = 1;
System.out.println("Move" + n + "from" + from + " to " + mid);
int step3=process(n-1,left,mid,right,to,from);
int step4=1;
System.out.println("Move"+ n +" from "+ mid +" to "+to);
int step5=process(n-1,left,mid,right,from,to);
result=step1+step2+step3+step4+step5;
System.out.println("移动总步数"+ result);
}
return result;
}
public int hannuo1(int n,String left,String mid,String right){
if(n<1){
return 0;
}
return process(n,left,mid,right,left,right);
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
System.out.println("please input the nummber:");
int n=scan.nextInt();
hannuo han=new hannuo();
han.hannuo1(n,"left","mid","right");
}
}
运行结果:
方法二:非递归
非递归我们自然而然的想到栈,把左,中,右三个地点抽象成栈
代码实现:
class State
{
public int n;
public String left;
public String mid;
public String right;
public State(int n, String left, String mid, String right)
{
this.n = n;
this.left =left;
this.mid =mid;
this.right =right;
}
}
//栈
class StateStack {
private State[] stack = new State[1000];
//栈顶
private int top = 0;
//入栈
public void push(State s) {
stack[top++] = s;
}
//出栈
public State pop() {
if (top > 0) {
return stack[--top];
}
return null;
}
}
public class hannuota2 {
public static void hannuota2(int n, String left,String mid, String right) {
//创建一个栈
StateStack s = new StateStack();
//将开始状态进栈
s.push(new State(n,"left", "mid","right"));
//保存出栈元素
State state = null;
//出栈
while ((state = s.pop()) != null) {
//如果n为1,直接移动left->right
if (state.n == 1) {
move(state.left, state.right);
}
//如果n大于1,则按照递归的思路,先处理hanoi(n-1,left,right,mid),再移动left->right(等价于hanoi(1,left,mid,right) ),然后处理hanoi(n-1,mid,left,right),因为是栈,所以要逆序添加
else {
//栈结构先进后出,所以需要逆序进栈
s.push(new State(state.n - 1, state.mid, state.left, state.right));
s.push(new State(1, state.left, state.mid, state.right));
s.push(new State(state.n - 1, state.left, state.right, state.mid));
}
}
}
public static void move(String str1, String str2) {
System.out.println(str1 + "->" + str2);
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("please input the nummber:");
int n = scan.nextInt();
hannuota2(n, "left", "mid", "right");
}
}