Python算法 - 递归精解 - 汉诺塔问题

汉诺塔问题

题意

将A 柱子上的块转移到 C 上

条件1  -  每次只能转移一块

条件2  -  大块不能压小快

解析

概念原理

冰箱装大象问题

1. 打开冰箱

2. 放入大象

3. 关上冰箱

类比在 任何一个块 n 来说

1. 把上面的块都移动好

2. n 块移动过去

3. 之前上面的块在放在 n 块上面

简化问题, 考虑 123块的移动, 可以考虑成我想移动 3 . 必然要移动12

同理 我想移动 2, 必然要移动 1 , 即关系为

f(3) ---> f(2) ---> f(1)    问题分解为 3, 2, 1 块的独立流程, 即反向推引

f(3)  ==>  f(1) + (2)     3 块的前提是 2,1 的问题处理

f(2)  ==>  f(1)    2 块的前提是 1 的问题处理

流程解析

用人来比喻的话, 每个块都有个工人负责

工人n 有三个能力

1. 只能移动 第 n 块到任何柱子

2. 工人 n 可以叫人帮他处理压在他上面的块  (让 工人n-1 处理)

3. 工人 n 最后的工作是搬动 第n 块到目标柱子上

搬动的时候要确定的是你要从哪个柱子搬到哪个柱子。

题目中有三个柱子。 第一个起始柱子, 第三个目标柱子, 那剩下一个就是转移柱

转移柱子可以作为中转站, 最终目标是到三柱。

在步骤三之前。 只能将上面的块都放在中转的二柱上

代码实现

def hnt(index, start, mid, end):
    # 最后的人只有一个工作就是把第一个块移动到终点
    if index == 1:
        print "{}--->{}".format(start, end)
    else:
        # 叫人来把上面的块搬走, 先放在 mid 上做中转
        hnt(index - 1, start, end, mid)
        # 自己把自己的块搬到目标柱
        print "{}--->{}".format(start, end)
        # 叫人把之前的块搬回来, 之前在 mid 上, 现在要放在 end 上, 用 start 中转
        hnt(index - 1, mid, start, end)

if __name__ == ‘__main__‘:
    hnt(3, "A", "B", "C")

    # A--->C
    # A--->B
    # C--->B
    # A--->C
    # B--->A
    # B--->C
    # A--->C

原文地址:https://www.cnblogs.com/shijieli/p/12606985.html

时间: 2024-11-09 19:33:03

Python算法 - 递归精解 - 汉诺塔问题的相关文章

递归--练习2--noi6261汉诺塔

递归--练习2--noi6261汉诺塔 一.心得 先把递推公式写出来,会很简单的 二.题目 6261:汉诺塔问题 总时间限制:  1000ms 内存限制:  65536kB 描述 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到中间的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面. 这是一个著名的问题,几乎所有的教材上都有这个问题.由于条件是一次只能移动一个盘,且不允许大盘放

数据结构基础(6)--递归和函数调用--汉诺塔问题C语言实现

函数调用 通常,当一个函数运行期间调用另一个函数时,在运行被调函数之前,系统需要完成3件事: (1)将所有的实参,返回地址(个人理解是调用被调函数时的下一个语句的地址)等信息传递给被调函数保存. (2)为被调函数的局部变量分配存储空间. (3)将控制转移到被调函数入口. 从被调函数返回调用函数之前,系统完成3件事: (1)保存被调函数的计算结果. (2)释放被调函数的数据区. (3)依照被调函数保存的返回地址,将控制转移到调用函数. 递归: 一个函数自己直接或间接调用自己. 思想就是:将问题规模

编程:递归编程解决汉诺塔问题(用java实现)

//Li Cuiyun,October 14,2016.//用递归方法编程解决汉诺塔问题package tutorial_3_5;import java.util.*; public class HanoiTower { public static void main(String[] args) { // TODO Auto-generated method stub @SuppressWarnings("resource") Scanner sc=new Scanner(Syste

经典递归小程序--汉诺塔

#include <stdio.h> /* 思路:1.将1到n-1号盘子借助C移到B上 2.将n号盘子移到C上 3.将1到n-1号盘子借助A移到C上 */ //初始化步数 int i = 0; void move(int,char,char); void hannuota(int,char,char,char); void main(void){ int n; printf("请输入汉诺塔盘子的个数:"); scanf("%d",&n); han

JavaScript递归函数解“汉诺塔”

"汉诺塔"是一个著名的益智游戏.塔上有3根柱子和一套直径各不相同的空心圆盘.开始时柱子上的所有圆盘都按照从小到大的顺序堆叠.目标是通过每次移动一个圆盘到另一根柱子,最终把一堆圆盘移动到目标柱子上,过程中不允许把交大的圆盘放置在较小的圆盘之上. 仔细解读这段话,如果有10个圆盘甚至更多,那操作步骤绝对多到让人震惊,但目标是把一堆圆盘移动到目标柱子上,如果把上面的9个圆盘看成一套,第10个圆盘看成另一套,先移动9个圆盘到另一根柱子上,再把上面8个圆盘看成一套,第9个圆盘看成另一套--依次类

关于C++的递归(以汉诺塔为例)

关于C++,hanoi塔的递归问题一直是个经典问题,我们学习数据结构的时候也会时常用到, 因为它的时间复杂度和空间复杂度都很高,我们在实际的应用中不推荐使用这种算法,移动n个盘子, 需要2的n次幂减一步,例如:5个盘子,31步:10个盘子,1023步. 下面,是我整理的有关C++递归的代码实现过程,希望对大家的学习有所帮助. #include <iostream> using namespace std; //第一个塔为初始塔,中间的塔为借用塔,最后一个塔为目标塔 int step=1;//记

【算法与数据结构】汉诺塔问题Java实现

思路:递归 [代码] 1 public class Main { 2 public static void hanoi(int n, int x, int y, int z) { 3 if (n == 1) { 4 System.out.print(x + "----->" + z); 5 }else { 6 hanoi(n - 1, x, z, y);//把前面n-1个移动到y上 7 System.out.print(x + "----->" + y)

【数据结构与算法】递归汉诺塔

汉诺塔 汉诺塔是根据一个传说形成的数学问题(关于汉诺塔): 有三根杆子A,B,C.A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小.要求按下列规则将所有圆盘移至C杆: 每次只能移动一个圆盘: 大盘不能叠在小盘上面. 提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则. 递归汉诺塔 解题思路: 可以把问题简化成2个盘子的情况,如:A上有两个盘子,B和C是空的.如果要把A的两个盘子全部移动到C,需要经过以下步骤: 1.A移动一个盘子到B 2.A移动一个盘

算法笔记_013:汉诺塔问题(Java递归法和非递归法)

目录 1 问题描述 2 解决方案  2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus is possible for using animation. e.g. if n = 2 ; A→B ; A→C ; B→C; if n = 3; A→C ; A→B ; C→B ; A→C ; B→A ; B→C ; A→C; 翻译:模拟汉诺塔问题的移动规则:获得奖励的移动方法还是有可能的.