zoukankan      html  css  js  c++  java
  • 汉诺塔问题

    题目:汉诺塔问题,更改规则,限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧。只能通过中间的塔,求当塔N层的时候,打印最优移动过程和最优移动总步数。

    当塔只有两层时,最上层的塔记为1,最下层的塔记为2,则打印: 

      Move 1 from 左 to 中
      Move 1 from 中 to 右
      Move 2 from 左 to 中
      Move 1 from 右 to 中
      Move 1 from 中 to 左
      Move 2 from 中 to 右
      Move 1 from 左 to 中
      Move 1 from 中 to 右
      移动次数为:8

    采用递归方法解决:

      首先:当只剩下最上层的塔需要移动时,总的有两种情况:   

         1.两侧移动,从左侧移动到右侧,从右侧移动到左侧, 需要两步,例如左->右: 左->中, 中->右。打印Move 1 from 左 to 中  ,Move 1 from 中 to 右

         2.两侧移动中间位置,只需一步

      以上过程是递归地终止条件。

      接下来,我们分析多层塔的情况:

        如果剩下N层塔,从最上面到最下面为1~N,则有如下判断:

        1.如果剩下的N层塔都在左边,希望向中间移动,则需要3步

        1)将1~N-1移动到右边,交给递归实现

        2)将N移动到中间

        3)将1~N-1移动到中间,交给递归实现

        其他几种如N层塔,在中移动到左 和 中到右,右到中,都是3步。

        2.如果剩下的N层塔在左边,希望向右移动,需要5步

        1)将1~N-1移动到右边,交给递归

        2)将N移动到中间

        3)将1~N-1从右->左,递归实现

        4)N: 中->右

        5)1~N-1 : 左->右 递归实现

     代码:

      

    package chapter_1;
    
    /**
     * 递归调用汉诺塔
     */
    public class Solution6 {
    
        public static int hanoiProblem1(int num, String left, String mid, String right){
            if(num < 0){
                return 0;
            }
            return process(num, left, mid , right, left, right);
        }
    
        private static int process(int num, String left, String mid, String right, String from, String to) {
            if(num == 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)){//起点或者终点为mid情况
                //将N层 左->中,中->左, 中->右,右->中,
                String another = (from.equals(left) || to.equals(left)) ? right : left;
                /**
                 * 左->中:  1-N-1,left->right; N, left -> mid; 1-N-1 right->mid
                 */
                int part1 = process(num - 1, left, mid, right, from, another); //N-1 left->right
                int part2 = 1; // N left->mid
                System.out.println("Move " + num + " from " + from + " to " + to);
                int part3 = process(num - 1, left, mid, right, another, to);
                return part1 + part2 + part3;
            }else {
                int part1 = process(num-1, left, mid, right, from, to);
                int part2 = 1;
                System.out.println("Move " + num + " from " + from + " to " + mid);
                int part3 = process(num -1, left, mid, right, to, from);
                int part4 = 1;
                System.out.println("Move " + num + " from " + mid + " to " + to);
                int part5 = process(num - 1, left, mid, right, from, to);
                return part1 + part2 + part3 + part4 + part5;
            }
    
        }
    }
  • 相关阅读:
    windows update error 0x8024401c
    linux杀毒软件ClamAV的安装使用
    firewalld防火墙设置
    RPM-GPG-KEY详解
    centos修改默认启动级别
    debian9.6修改系统语言
    ubuntu18.04修改网卡名称为eth0
    Windows server 1709(不含UI)模板部署
    NVIDIA-SMI系列命令总结
    bash: lspci: command not found解决方法
  • 原文地址:https://www.cnblogs.com/huangyichun/p/6254108.html
Copyright © 2011-2022 走看看