博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
汉诺塔【模拟】
阅读量:5272 次
发布时间:2019-06-14

本文共 1159 字,大约阅读时间需要 3 分钟。

题目大意:

古老的汉诺塔问题是这样的:用最少的步数将N个半径互不相等的圆盘从1号柱利用2号柱全部移动到3号柱,在移动的过程中小盘要始终在大盘的上面。

现在再加上一个条件:不允许直接把盘从1号柱移动到3号柱,也不允许直接把盘从3号柱移动到1号柱。
把盘按半径从小到大用1到N编号。每种状态用N个整数表示,第i个整数表示i号盘所在的柱的编号。则N=2时的移动方案为:
(1,1)=>(2,1)=>(3,1)=>(3,2)=>(2,2)=>(1,2)=>(1,3)=>(2,3)=>(3,3)
初始状态为第0步,编程求在某步数时的状态。

思路:

如果把汉诺塔的变化打出来,那么就是这样的:

  1. (1,1,1)
  2. (2,1,1)
  3. (3,1,1)
  4. (3,2,1)
  5. (2,2,1)
  6. (1,2,1)
  7. (1,3,1)
  8. (2,3,1)
  9. (3,3,1)
  10. (3,3,2)
  11. (2,3,2)
  12. (1,3,2)
  13. (1,2,2)
  14. (2,2,2)
  15. (3,2,2)
  16. (3,1,2)
  17. (2,1,2)
  18. (1,1,2)
  19. (1,1,3)
  20. (2,1,3)
  21. (3,1,3)
  22. (3,2,3)
  23. (2,2,3)
  24. (1,2,3)
  25. (1,3,3)
  26. (2,3,3)
  27. (3,3,3)

然后,就能发现: 

1号圆盘在移动3次中,共移动了2次;2号圆盘在移动9次中,共移动了2次;3号圆盘在移动27次中,共移动了2次。 
那么也就很容易推出:n号圆盘每移动3n次中,会移动两次! 
那么这道题就很好做了,预处理3n3n,每次可以利用周期问题求出答案。 
时间复杂度:O(tn),最坏950000

 

代码:

1 #include 
2 #include
3 #include
4 using namespace std; 5 6 const char o[]={
'1','2','3','2'}; 7 int t,n,m,num[31],k; 8 9 int main()10 {11 scanf("%d",&t);12 num[0]=1;13 for (int i=1;i<=19;i++)14 num[i]=num[i-1]*3; //预处理15 while (t--) //t组数据16 {17 scanf("%d%d",&n,&m);18 if (!m) //特判,没有移动19 {20 for (int i=1;i

 

转载于:https://www.cnblogs.com/hello-tomorrow/p/9314781.html

你可能感兴趣的文章
BZOJ3438: 小M的作物
查看>>
GB2312简体中文编码表
查看>>
Thinkphp或查询使用
查看>>
[No0000F2]ip安全监视器
查看>>
【数据挖掘】机器学习的几何观点
查看>>
matlab画柱状图
查看>>
空类 sizeof 为什么是1
查看>>
iOS学习笔记1--在xcode6以上的版本中不使用storyboard以及部分控件使用
查看>>
C#语言之“中英文混合字符串对齐”的方法
查看>>
linux 正则表达式
查看>>
微信占比降至4成 手游团队转向H5
查看>>
Android WakeLock 使用总结
查看>>
qt中的lineEdit文本输入框的输入类型限制(三种验证类)
查看>>
MVC校验
查看>>
插入排序
查看>>
hbase
查看>>
七:程序是在何种环境下运行的
查看>>
jmeter聚合报告导出时乱码的解决
查看>>
基于VM10+Win7安装Mac OSX10.11 El Capitan
查看>>
支付宝支付成功,return_url.php返回数据为空解决办法
查看>>