汉诺塔问题及其变种
来源:互联网 发布:nginx 80端口无法访问 编辑:程序博客网 时间:2024/04/29 18:57
1.ABC三个柱子,小的不能在大的上面。从A移到C.
//分析一下可知,每一次想要将一个大盘子从A移到C,就必须先把上面的小盘子从A移到B,最后再把B的盘子移到C,这样就是一个递归的过程。
#include <iostream>using namespace std;int num=0;void hanio(int a,int b,int c,int n){ if(n<1) return; hanio(a,c,b,n-1); num++; hanio(b,a,c,n-1);}int main(){ int n; cin>>n;num=0; hanio(1,2,3,n); cout<<num<<endl; return 0;}
当然,直接输出规律也行,答案就是1<<n-1;
2.4个柱子
/*
多了一根柱子而已,但是一看就懵了啊...
是这样的,从A到D的话,设有m个盘子从A到B步数为f[m],那么剩下的n个盘子就服从三个柱子的汉诺塔问题了。最后再从B到D,也是同样的步数。
所以对于n取min(f[m]*2+(1<<(n-m))-1);
*/
#include <iostream>using namespace std;long long f[101];int main(){ f[1]=1; f[2]=3; int n; cin>>n; for(int i=3;i<71;i++){ f[i]=2*f[1]+(1<<(i-1))-1; for(int j=2;j<i;j++){ f[i]=min(f[i],f[j]*2+(1<<(i-j))-1); } } cout<<f[n]<<endl; return 0;}
3.AC之间不能联通,任何操作都必须经过B..
/*
这个没有上一题难。
第n个盘子从A到C,必须要用到n-1个盘子的结果。
f[n]=f[n-1]+1+f[n-1]+1+f[n-1]=3f[n-1]+2;
*/
#include <iostream>using namespace std;long long f[101];int main(){ f[1]=2; int n; cin>>n; for(int i=2;i<71;i++){ f[i]=f[i-1]*3+2; } cout<<f[n]<<endl; return 0;}
4.在第三题的基础上,允许最大的一个盘子放在小盘子上面。
/*
n个盘子从A移动到C等于n-1个盘子从A移动到B,第n个盘子从A到C,n-1个盘子从B到C。
那么f[x]表示x个盘子从A到B。
从A到B和从B到C是一样的步数。
/*
#include <iostream>using namespace std;long long f[101];int main(){ f[1]=1; int n; cin>>n; for(int i=2;i<=n;i++){ f[i]=3*f[i-1]+1; } cout<<2*f[n-1]+2<<endl; return 0;}
5.普通汉诺塔问题,问你a个盘子从小到大第b个盘子动了多少下。
/*
最下面的盘子动了1次
第二个动了2次
第三个动了4次.....
总之就是输入a,b,输出 (1<<(a-b)).不写代码了。数据量不大,不需要快速幂。
*/
6.
给n个盘子,大不能压小,问在3根柱子上有多少种摆放方式。
//每个盘子3种,一共3^n
7.
给定每个柱子的各个盘子的大小,求问这种情况可不可能出现。
/*
这道题需要思考。
从最大的开始找。它一定是在A或者在C上。如果在B上面就是错的。
若n在A上面,那么倒数第二大的不是在B上,就是在C上;若n在C上,倒数第二大的不是在A上,就是在B上。
以此类推即可。
可以参考第一题的递归函数,有没有一种返璞归真的感觉?
*/
#include <iostream>using namespace std;int dfs(int k,int a[],int b[],int c[]){ if(k==b[0]) return 0; if(k==a[0]) return dfs(k-1,a+1,c,b); if(k==c[0]) return dfs(k-1,b,a,c+1); return 1;}int main(){ int n; int a[100],b[100],c[100]; cin>>n; int tem; cin>>tem; for(int i=0;i<tem;i++) cin>>a[i]; cin>>tem; for(int i=0;i<tem;i++) cin>>b[i]; cin>>tem; for(int i=0;i<tem;i++) cin>>c[i]; if(dfs(n,a,b,c)) cout<<"true"<<endl; else cout<<"false"<<endl; return 0;}
阅读全文
0 0
- 汉诺塔问题及其变种
- Josephus约瑟夫问题及其变种
- 变种汉诺塔问题
- 汉诺塔问题的一个变种
- 动态规划求解最大字段和及其变种问题
- 动态规划求解最大字段和及其变种问题
- 逆序对及其变种问题的一点思考
- 哈希链表及其变种
- B树及其变种
- 螺旋矩阵及其变种
- 哈希链表及其变种
- bn 层及其变种
- 快速排序及其变种算法
- LBP特征及其一些变种
- MVC 编程模式及其变种
- 二分查找算法及其变种
- Linux内核 - 哈希链表及其变种
- 二分查找算法及其变种
- hill-climbing algorithm 爬山算法简介
- java权限修饰
- VS中常见的环境变量
- 日期的计算多少天 多少月 多少年后 前台通过了ajax调用后台处理获取返回值
- Qt下双屏的显示方法
- 汉诺塔问题及其变种
- Linux Shell 流程控制语句实例及自定义函数介绍
- 欢迎使用CSDN-markdown编辑器
- nlp-形式语言与自动机-ch09-词义消歧
- Android.mk语法解释
- 002
- 字节转string
- C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
- linux 用户管理