汉诺塔问题II

今天看了一本书上的一个汉诺塔问题,和原本的汉诺塔问题有点不一样,就记录了下来。

package com.an.stack;

/*
 * 汉诺塔问题(II)
 *   这里的汉诺塔修改了游戏规则,现在限制不能直接从左边的塔放到最右边,也不能从右边直接放到
 * 	   左边,而是必须要经过中间.问:当有N层时,写出打印出的移动过程和最优移动的步数
 * 
 * 	分析:如果剩下N层塔,从上到下一次为1~N,则有如下判断:
 * 1.如果剩下N层塔都在左边,希望全部放到中,则有三个步骤
 * 	① 将1~N层塔从左边放到右边,利用递归
 * 	② 再将第N层塔从左边放到中间
 * 	③ 再将N-1层塔从右边放到中间
 * 2.如果剩下N层塔从“中”移到“左”,从“右”移到“中”,从“中”移到“右”,方法和1过程一样
 * 	  也分为3个步骤。
 * 3.如果剩下的N层塔都在左,希望移到右边.共分为5个步骤
 * 	① 将N-1层塔全部移到右边,利用递归
 *  ② 将第N层塔从左移到中。
 *  ③ 将N-1层塔全部由右全部移到左边
 *  ④ 将第N层塔从中移到右
 *  ⑤ 将N-1层塔从左全部移到右,利用递归
 * 4.如果剩下的N层塔都在右,希望移到左边.共分为5个步骤,和情况三一样
 * 
 */
public class HanioProblem1 {
	static int i=1;
	public static void main(String[] args) {
		HanioProblem1 hanio = new HanioProblem1();
		hanio.hanioProblem(2, "A", "B", "C");
		System.out.println("共需要"+ (i-1) +"步");
	}
	

	public int hanioProblem(int n,String left,String mid,String right){
		if(n < 0){
			return 0;
		}
		return process(n,left,mid,right,left,right);
	}

	private 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  +" 第"+(i++)+"步");
				return 1;
			}else{
				System.out.println("Move 1 from "+from + " to " + mid+" 第"+(i++)+"步");
				System.out.println("Move 1 from "+mid + " to " + to+" 第"+(i++)+"步");
				return 2;
			}
		}
		if(from.equals(mid) || to.equals(mid)){
			String another = (from.equals(left))||(to.equals(left))? right:left;
			int part1 = process(n-1, left, mid, right, from, another);
			int part2 = 1;
			System.out.println("Move "+n+" from "+from+" to "+to+" 第"+(i++)+"步");
			int part3 = process(n-1, left, mid, right, another, to);
			
			return part1 + part2 + part3;
		}else{
			int part1 = process(n-1, left, mid, right, from, to);
			int part2 = 1;
			System.out.println("Move " +n+" from "+ from + " to "+mid+" 第"+(i++)+"步");
			int part3 = process(n-1, left, mid, right, to, from);
			int part4 = 1;
			System.out.println("Move "+n+" from "+mid + " to "+right+" 第"+(i++)+"步");
			int part5 = process(n-1, left, mid, right, from, to);
			
			return part1+part2+part3+part4+part5;
		}
	
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值