返回顶部

递归--一个十分magic的思想

 

 

汉诺塔问题

次数问题

复制代码
#include <iostream>

using namespace std;


/*
    将n个盘子从x搬到z 可以转化为  先n上方n-1个盘子搬到y,再把n这个盘子搬到z,最后将n-1个盘子从y搬到z。依次类推。
    即f(n) 的问题可以转化为f(n-1)的问题,...,f(1);

    三根柱子 分别用 x y z 表示
    伪代码如下:
    int fz(int n)
    {
        if(n == 1) return 1;
        else
            return fy(n-1) + 1 + fz(n-1);
    }
*/
unsigned long long f(int n)
{
    if (n == 1) return 1;
    else
        return 2 * f(n - 1) + 1;
}

int main() {

    // test 
    cout << "step cnt " << f(3) << endl;  // 3个盘子  从0搬运到2
    cout << "step cnt " << f(4) << endl;  // 4个盘子  从0搬运到2
    cout << "step cnt " << f(64) << endl; // 64个盘子 从0搬运到2
    /*
    step cnt 7
    step cnt 15
    step cnt 18446744073709551615  // 这个数字超过了long long 的范围,这里用unsigned long long
    */

}
复制代码

64个金盘,如果每秒移动一个,那么按照它的这个规则需要5849亿年。

 

搬运步骤问题

我们假设搬运n个盘子,且他们的序号为1-n。三个柱子的索引为0,1,2。

使用(plateNo,fromIdx,toIdx) 三个数的元组来表示每一次搬运的过程。有了这个数据结构,我们也可以用代码可视化的展示汉诺塔的搬运过程。

则有如下递归程序来描述搬运过程

复制代码
#include <iostream>
#include <vector>

using namespace std;


void f(int n,int fromIdx,int toIdx,vector<vector<int>>& vvRet)
{
    if(n == 1)
        vvRet.push_back({1,fromIdx,toIdx});
    else
    {
        f(n-1,fromIdx,3-fromIdx-toIdx,vvRet);
        vvRet.push_back({n,fromIdx,toIdx});
        f(n-1,3-fromIdx-toIdx,toIdx,vvRet);
    }
}


int main() {
    
    // test 
    vector<vector<int>> vvRet;
    //f(3,0,2,vvRet);  // 3个盘子 从0搬运到2
    /*
    ( 1, 0, 2 )
    ( 2, 0, 1 )
    ( 1, 2, 1 )
    ( 3, 0, 2 )
    ( 1, 1, 0 )
    ( 2, 1, 2 )
    ( 1, 0, 2 )
    */
    f(4,0,2,vvRet);  // 4个盘子 从0搬运到2
    /*
    ( 1, 0, 1 )
    ( 2, 0, 2 )
    ( 1, 1, 2 )
    ( 3, 0, 1 )
    ( 1, 2, 0 )
    ( 2, 2, 1 )
    ( 1, 0, 1 )
    ( 4, 0, 2 )
    ( 1, 1, 2 )
    ( 2, 1, 0 )
    ( 1, 2, 0 )
    ( 3, 1, 2 )
    ( 1, 0, 1 )
    ( 2, 0, 2 )
    ( 1, 1, 2 )
    */
    for(auto item:vvRet)
    {
        cout << "( "<<item[0]<<", "<<item[1]<<", "<<item[2]<<" )"<<endl;
    }

}
复制代码

 

posted @   Zcb0812  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示

目录导航