汉诺塔问题(修改版)(java实现)

【题目】
  汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。求当塔有N层的时候,打印最优移动过程和最优移动总步数。

【代码实现】
  

class Demo{
    public static void main(String[] args){
        int i = hanoi(3,"a","b","c","a","c");
        System.out.println("总步数:" + i );
    }
    //num表示盘子的总数,left是左边的柱子,mid是中间的柱子,right是右边的柱子,from是起始的柱子,to是终止的柱子
    public static int hanoi(int num,String left,String mid,String right,String from,String to){
        //盘子数目小于1的时候,不用移动,返回步数为0
        if(num<1){
            return 0;
        }
        //如果只剩下一个最顶层的盘子,分两种情况,递归的终止条件
        if(num==1){
            //如果起始柱子是中间或者终止柱子是中间,那么只用移动一步就好
            //如果起始柱子和终止柱子都不是中间,那么根据题目,就需要先从起始移动到中间,再从中间移动到右边,也就是需要移动两步
            if(from.equals(mid) || to.equals(mid)){
                System.out.println("move" + num + " " + from + "->" + "to" );
                return 1;
            }else{
                System.out.println("move" + num + " " + from + "->" + mid);
                System.out.println("move" + num + " " + mid + "->" + to);
                return 2;
            }
        }
        //如果剩余的盘子数量大于1,分两种情况
        //情况一:
        //如果起始柱子是中间或者终止柱子是中间,那么需要三步
        //第一步:将第1 — num-1个盘子从起始柱子移动到临时柱子,用递归实现
        //第二步:将第num个盘子从起始柱子移动到终止柱子
        //第三步:将第1 — num-1个盘子从临时柱子移动到终止柱子,用递归实现
        //最后返回三步的步数总和
        //情况二:
        //如果起始柱子和终止柱子不是中间,那么无非就是从最左边的柱子移动到最右边的柱子或者从最右边的柱子移动到最左边的柱子,那么需要五步
        //第一步:将第1 — num-1个盘子从起始柱子移动到终止柱子,用递归实现
        //第二步:将第num个盘子从起始柱子移动到中间的柱子(因为中间一定是空的)
        //第三步:将第1 — num -1个盘子从终止柱子移动到起始柱子,用递归实现
        //第四步:将第num个盘子从中间柱子移动到终止柱子
        //第五步:将第1 — num-1个盘子从起始柱子移动到终止柱子
        if(from.equals(mid) || to.equals(mid)){
            //another用来确定那个是临时的柱子
            String another = (from.equals(left) || to.equals(left))?right:left;
            int part1 = hanoi(num-1,left,mid,right,from,another);
            int part2 = 1;
            System.out.println("move" + num + " " + from + "->" + to);
            int part3 = hanoi(num-1,left,mid,right,another,to);
            return part1+part2+part3;
        }else{
            int part1 = hanoi(num-1,left,mid,right,from,to);
            int part2 = 1;
            System.out.println("move" + num + " " + from + "->" + mid);
            int part3 = hanoi(num-1,left,mid,right,to,from);
            int part4 = 1;
            System.out.println("move" + num + " " + mid + "->" + to);
            int part5 = hanoi(num-1,left,mid,right,from,to);
            return part1+part2+part3+part4+part5;
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值