首页 > 其他分享 >汉诺塔问题

汉诺塔问题

时间:2023-04-26 23:22:16浏览次数:37  
标签:移到 idx hanoi 问题 盘移 汉诺塔 移动 号盘

移动步骤

三根柱子A,B,C。A杆上有N个N>1N>1穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:*

  1. 每次只能移动一个圆盘;
  2. 大盘不能叠在小盘上面。

汉诺塔


解法一:

使用递归

分析:

  1. 当只有一个时,只需把第一个盘从a移到c
  2. 两个时,先把第一个盘从a移到b,再把第二个盘从a移到c,最后把第一个盘从b移到c
  3. 三个时,将1号盘移到c,2号盘移到b,1号盘移到b,(此时1,2号盘放在b),3号盘移到c,(将1,2号盘从b移到c)1号盘移到a,2号盘移到c,1号盘移到c
  4. 四个时,1从a到b,2从a到c,1从b到c,3从a到b,1从c到a,2从c到b,1从a到b,(此时1,2,3号盘在b),4从a到c,(将1,2,3号盘从b移到c)1从b到c,2从b到a,1从c到a,3从b到c,1从a到b,2从a到c,1从b到c
  5. ...可以看出从两个盘开始,都是将最后一个盘上面的盘移到b,在将最大盘移到目标柱后,再把在b的盘移动到c
  6. n个盘时,将n-1个盘从a移动到b,直接移动不成立,所以借助c,形成a->c->b,随后将n移动到c后,将n-1盘从b移到c——也就是先将n-2个盘从b移到a,可以将a,b,c看做一个圆圈上的三个柱子,所以这时的移动方式是b->c->a,将n-1盘放到c。
  7. 重复操作直到完成

思路:

  1. 如果只有一个盘,直接从a到c
  2. 按照分析,两个以上的盘的规律是:
    • 将n-1个盘放到b
    • 将n盘移动c
    • 将n-1盘移到c(过程和上两步相同,只是起始柱从a变成了b

代码:

//设置变量接收盘数和柱的名称
var hanoi = function(n,a,b,c){
    //一个盘是直接移动
    if(n == 1){
        console.log(`将${n}从${a}移到${c}`)
    }else{
        //使用递归,直到只有一个盘,然后回溯到n
        //先将n-1个盘放到b
        hanoi(n-1,a,c,b)
        //将n盘移到c
        console.log(`将${n}从${a}移到${c}`)
        //将n-1盘移到c
        hanoi(n-1,b,a,c)
    }
}
//时间复杂度O(2^n),随着n的增加,消耗时间成指数增长
//简化
var hanoi = function(n,a,b,c){
    //一个盘是直接移动
    if(n > 0){
        //使用递归,直到只有一个盘,然后回溯到n
        //先将n-1个盘放到b
        hanoi(n-1,a,c,b)
        //将n盘移到c
        console.log(`将${n}从${a}移到${c}`)
        //将n-1盘移到c
        hanoi(n-1,b,a,c)
    }
}

解法二:崩了

分析:

从解法一的分析可以看出n为偶数的移动方式

盘号 移动方式
1 1.a->b 3.b->c 5.c->a 7.a->b 9.b->c 11.c->a 13.a->b 15.b->c
2 2.a->c 6.c->b 10.b->a 14.a->c
3 4.a->b 12.b->c
4 8.a->c

奇数号盘的移动规律是a->b->c->a循环

偶数号盘是a->c->b->a循环

而n为奇数时正好相反

盘的移动顺序为1,2,1,3,1,2,1,4,1,2,1,3,1,2,1

1盘在1,3,5,7,9,11,13,15时移动 转为二进制为1,11,101,111,1001,1011,1101,1111

2盘在2,6,10,14时移动 10,110,1010,1110

3盘在4,12时移动 100,1100

4盘在8时移动 1000

可以说奇数盘比偶数盘多移一个柱

奇数:a->b->c->a

偶数:a-b->c-a->b-c->a-b->c

循环遍历最后一个1后面0的个数

时间复杂度2^n*?

思路:

  1. 判断盘数的奇偶,创建数组记录盘所在的柱
  2. 循环2^n-1,将每一个数转换成二进制字符串,并循环遍历最后一个1后面的0的个数,根据0的个数判断移动哪个盘,并更新柱

代码:

JavaScript


python

def hanoi(n):
    cols = ["A","B","C"] if n % 2 == 0 else ["A","C","B"]
    pan = [0] * n #盘的id == 柱的id
    for step in range(1,2**n):
    	idx = len(bin(step & -step)) - 3 #lowbit 转二进制,开头是0b1
    	old_tower = cols[golds[idx]]
        golds[idx] = (golds[idx] + 1 + idx % 2) % 3  # 奇数比偶数多走一步
        print(f"step{step}: 将{idx + 1}号金片从{old_tower}移到{cols[golds[idx]]}")

hanoi(4)

标签:移到,idx,hanoi,问题,盘移,汉诺塔,移动,号盘
From: https://www.cnblogs.com/shallow-dreamer/p/17357712.html

相关文章

  • 13.糖果问题
       代码1实现:#include<stdio.h>intjudge(intsw[]);//判断每个孩子的手中糖果是否一致voidprint(intc[]);//打印每个孩子手里的糖果数intj=0;//记录分配的次数intmain(intargc,constchar*argv[]){intsweet[10]={10,2,8,22,16,4,10,6,14,20};intt[10];pri......
  • macos Python.运行时,遇到这个问题:ImportError: ('Unable to load OpenGL library', "
    问题安装https://gitee.com/mirrors/animated-drawings这个部署时,安装环境出现如下问题:pycharm下打开这个文件:python3.9/site-packages/OpenGL/platform/ctypesloader.py在79行下修改如下:......
  • 小知识:使用errorstack定位特定问题
    有客户遇到ORA-2289的报错,同事协助去现场排查,我帮着远程共同check下。客户只是应用端报出的错误,为了进一步定位,服务端需要开errorstack协助定位具体问题。下面就以这个ORA-2289为例,示范下errorstack的使用方法。--开启errorstackaltersystemsetevents'2289tracenameerr......
  • 毕设相关问题
    Stride的作用:是成倍缩小尺寸,而这个参数的值就是缩小的具体倍数,比如步幅为2,输出就是输入的1/2;步幅为3,输出就是输入的1/3。卷积神经网络(CNN)有卷积层和池化层结构,这两层结构是CNN的重要组成部分。卷积层就是通过若干个卷积核对上一层输入进行扫描,从而在较大程度上提取原始像素矩阵......
  • 【Node】coderwhy node 项目视频中 jwt.sign 没有返回值的问题
    在写登录接口时,想生成token用于登录验证,但是在使用jwt生成token(jwt.sign())时却没有返回token,服务端没有报错但是使用postman验证接口时却没有得到正确的请求结果。如果你在使用openssl生成的private.key时是和coerwhy老师一样1024的话就会报错解决方法:最好是生成20......
  • 什么是低码平台?低代码平台能解决什么问题?
    低代码平台是近年来日益流行的一种新型软件开发工具。它们提供了一种更简单、更快速、更具成本效益的方式来构建和部署定制软件应用程序。在本文中,我们将探讨什么是低码平台,它们可以解决什么问题,以及它们为什么变得如此流行。一、什么是低代码平台?低代码平台是一种软件开发工具,允许......
  • 汉诺塔问题(递归)
    #include<iostream>usingnamespacestd;voidmove(intn,chara,charb,charc){ if(n==0) return; move(n-1,a,c,b); cout<<a<<"-->"<<c<<endl; move(n-1,b,a,c);}intmain(){ intn; chara='......
  • day 17 爱因斯坦的数学问题
    1.循环遍历1~N;2.满足条件num%2==1,num%3==2,num%5==4,num%6==5,num%7==0;3.输出所有满足数;#include<iostream>usingnamespacestd;intmain(){intN;printf("请输入一个数:");cin>>N;for(intnum=1;num<=N;num++){if(num%2==1&&num%3==2&&am......
  • 存钱问题
    一、问题描述:假设银行整存整取的月利率为 二、设计思路: 三、程序流程图: 四、代码实现:#include<stdio.h>#include<math.h>intmain(){intx1,x2,x3,x5,x8;inty1,y2,y3,y5,y8;doubletemp;doublemax=0.0;for(x8=0;x8<=2;x8++){......
  • double精度丢失问题
    字面量,目的:告诉程序员数据在程序中该怎么书写字面量分类,整数小数字符字符串布尔值空值变量作用:内存中的一块区域,里面立业存储一个数据,存储的数据可以变化格式:树木类型变量名称=初始值;......