• 3145 code[VS]汉诺塔游戏递归


    3145 汉诺塔游戏

    题目描述 Description

    汉诺塔问题(又称为河内塔问题),是一个大家熟知的问题。在A,B,C三根柱子上,有n个不同大小的圆盘(假设半径分别为1-n吧),一开始他们都叠在我A上(如图所示),你的目标是在最少的合法移动步数内将所有盘子从A塔移动到C塔。

    游戏中的每一步规则如下:

    1. 每一步只允许移动一个盘子(从一根柱子最上方到另一个柱子的最上方)

    2. 移动的过程中,你必须保证大的盘子不能在小的盘子上方(小的可以放在大的上面,最大盘子下面不能有任何其他大小的盘子)

    如对于n=3的情况,一个合法的移动序列式:

    1 from A to C

    2 from A to B

    1 from C to B

    3 from A to C

    1 from B to A

    2 from B to C

    1 from A to C

    给出一个数n,求出最少步数的移动序列

    输入描述 Input Description

    一个整数n

    输出描述 Output Description

    第一行一个整数k,代表是最少的移动步数。

    接下来k行,每行一句话,N from X to Y,表示把N号盘从X柱移动到Y柱。X,Y属于{A,B,C}

    样例输入 Sample Input

    3

    样例输出 Sample Output

    7

    1 from A to C

    2 from A to B

    1 from C to B

    3 from A to C

    1 from B to A

    2 from B to C

    1 from A to C

    数据范围及提示 Data Size & Hint

    n<=10

    分类标签 Tags 点此展开 

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    void mov(int n,char A,char B,char C)
    {
    if(n==0)return;//没有要移动的,结束;
    if(n==1)
    {
    cout<<1<<" from "<<A<<" to "<<C<<endl;return;//当只移动1个时
    }
    mov(n-1,A,C,B);//将n-1个从a经过c移动到b;
    cout<<n<<" from "<<A<<" to "<<C<<endl;//输出从a移动到c;
    mov(n-1,B,A,C); //再从b经过a移动到c;
    }
    int main()
    {
    int n;
    scanf("%d",&n);
    cout<<pow(2,n)-1<<endl;//输出步骤数;
    mov(n,'A','B','C');//从A移到C经过B;
    return 0;
    }

    递归问题 :当数据很大时,怎么算都算不完,所以解决一个大问题时,我们从小问题入手;

    设步骤数为sum;

    n=0,sum=0;

    n=1,sum=1;

    n=2,sum=3;

    n=3,sum=7;

    发现 sum=pow(2,n)-1;

    也可以发现 当把n件物品从a--c时,一定要先将n-1件先取出,通过c先移到b,再将a中剩下的最后一件移到c上;

    可以说是每次都将最大的取出;

    所以过程是:先将n-1个取出放到b,再取最大的放到c底部,再将b的n-1个放到c;

    所以 f(n)=f(n-1)*2+1; (将n-1拿出来放回去一共两边,将最大放回去是1边)

  • 相关阅读:
    mysql 单表下的字段操作_查询
    mysql 表的操作
    mysql 单表下的字段操作
    mysql库的操作
    vim 复制&粘贴
    将系统剪贴板的内容粘贴到vim
    nc替代ping
    kali 将家目录下的中文文件名修改成英文
    Shiro反序列化漏洞检测、dnslog
    mac命令行切换python版本
  • 原文地址:https://www.cnblogs.com/zzyh/p/6598810.html
Copyright © 2020-2023  润新知