递归--一个十分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; } }
分类:
杂货堆
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?