汉诺塔I

题目链接:https://www.nowcoder.com/questionTerminal/7d6cab7d435048c4b05251bf44e9f185

题目大意:

  略

分析:

  利用汉诺塔与二进制的关系来做。

  如何用二进制解汉诺塔:https://www.bilibili.com/video/av7398130/

代码如下:

 class Hanoi {
public:
// 计算x的二进制位数
inline int getBits(int x) {
int cnt = ;
while(x >>= ) ++cnt;
return cnt;
} vector<string> getSolution(int n) {
vector< string > ans;
string s[] = {"left", "mid", "right"};
vector< int > arr;
arr.resize(n, );
// tot表示总移动次数
int tot = ( << n) - ;
int cnt = ;
while(cnt++ < tot) {
int lowbit = cnt & (-cnt);
int bitlen = getBits(lowbit) - ;
int b = + (n - bitlen) % ;// 偏移,b = 1往右,b = 2往左
ans.push_back("move from " + s[arr[bitlen]] + " to " + s[(arr[bitlen] + b) % ]);
arr[bitlen] = (arr[bitlen] + b) % ;
}
return ans;
}
};

汉诺塔II

题目链接:https://www.nowcoder.com/questionTerminal/b2d552cd60b7415fad2612a32e799812?toCommentId=2927834

题目大意:

  略

分析:

先给出4个盘子的表(三根柱子的序号分别为0, 1, 2):

容易看出n个盘子需要移动2n次。

  首先我们看红线分割的两块,令8~15行的0号,1号,2号盘子的位置加上2再模3,他们的数值刚好等于0~7行的0号,1号,2号盘子的位置。

  再看绿线分割的0~7行,另4~7行的0号,1号盘子的位置加上1再模3,他们的数值刚好等于0~3行的0号,1号盘子的位置。

  发现规律了没有?

  比如有汉诺塔的位置序列[2, 1, 1, 2],序列最后一个数为2,于是step([2, 1, 1, 2])就等于1000B + step([(2 + 2) % 3, (1 + 2) % 3,  (1 + 2) % 3]) = 1000B + step([1, 0, 0]),然后step([1, 0, 0])的最后一个数为0,于是step([1, 0, 0]) = step([1, 0]),直接往前进,并不需要上移,同理step([1, 0]) = step([1]), 对于step([1]),只有一个数字,直接取值,所以step([2, 1, 1, 2])最终等于1001B

  再比如有汉诺塔的位置序列[2, 0, 1, 2],序列最后一个数为2,于是step([2, 0, 1, 2])就等于1000B + step([(2 + 2) % 3, (0 + 2) % 3,  (1 + 2) % 3]) = 1000B + step([1, 2, 0]),然后step([1, 2, 0])的最后一个数为0,于是step([1, 2, 0]) = step([1, 2]),step([1, 2])的最后一个数字是2,于是step([1, 2]) = 10B + step([(1 + 2) % 3]) = 10B + step([0]), 对于step([0]),只有一个数字,直接取值,所以step([2, 1, 1, 2])最终等于1010B

  简单来说,就是末尾数字为0,就不变;末尾数字不为0,就让前面的数字加上这个数字再模3,然后求子问题,同时要加上这一位的权值,比如它是第5个数字,就要加上10000B;如果是第3个数字,就要加上100B

  不要问我原理,我是结合二进制找规律找出来的。

代码如下:

 class Hanoi {
public:
int chkStep(vector<int> &arr, int n, int b = ) {
if(n == ) return ;
int tmp = (arr[n - ] + b - ) % ;
return ( << (n - )) * (tmp != ) + chkStep(arr, n - , b + tmp);
}
};

汉诺塔I && II的更多相关文章

  1. 汉诺塔问题II(模拟)

    汉诺塔问题II Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 1556  Solved: 720 Description 汉诺塔(又称河内塔)问题是源于 ...

  2. HDU-1207 汉诺塔II

    汉诺塔  四根所需要的步数的规律: 规律:a[1]=1;a[2]=a[1]+2;a[3]=a[2]+2;(2个加2^1)a[4]=a[3]+4;a[5]=a[4]+4;a[6]=a[5]+4;(3个加 ...

  3. 汉诺塔系列问题: 汉诺塔II、汉诺塔III、汉诺塔IV、汉诺塔V、汉诺塔VI

    汉诺塔 汉诺塔II hdu1207: 先说汉若塔I(经典汉若塔问题),有三塔.A塔从小到大从上至下放有N个盘子.如今要搬到目标C上. 规则小的必需放在大的上面,每次搬一个.求最小步数. 这个问题简单, ...

  4. HDU 1207 汉诺塔II (找规律,递推)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1207 汉诺塔II Time Limit: 2000/1000 MS (Java/Others)     ...

  5. hdu 1207 汉诺塔II (DP+递推)

    汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  6. 1207 ACM 汉诺塔II 数学

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1207 中文题目,在原来三个柱子的情况下(汉诺塔一),增加了一个柱子,难度也增加了. 思路: 思考时尽量和汉 ...

  7. HDU 1207 汉诺塔II (递推)

    经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘.上 ...

  8. Hanoi II——汉诺塔步数求解进阶问题

    在NOJ上遇到关于汉诺塔步数的求解问题 开始读时一脸懵逼,甚至不知道输入的数据是什么意思 题目描述:给出汉诺塔的两个状态,从初始状态移动到目的状态所需要的最少步数 对于初级汉诺塔步数问题,我们可以直接 ...

  9. 汉诺塔III 递推题

    题目描述: 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动 ...

随机推荐

  1. Node.js 命令行工具的编写

    日常开发中,编写 Node.js 命令行工具来完成一些小任务是很常见的操作.其编写也不难,和日常编写 Node.js 代码并无二致. package.json 中的 bin 字段 一个 npm 模块, ...

  2. 『练手』005 Laura.SqlForever历史遗留 的 架构思想缺陷

    005 Laura.SqlForever历史遗留 的 架构思想缺陷 我们 比较一下 Laura.WinFramework 和 Laura.XtraFramework 的差异: Laura.WinFra ...

  3. DotNetCore跨平台~EFCore数据上下文的创建方式

    回到目录 对于DotNetCore来说,把大部分组件者放在DI容器里,在startup中进行注入,在类的构造方法中进行使用,如果某些情况下,无法使用这种DI的方式,也可以自己控制数据上下文的生产过程, ...

  4. 前端CSS学习-Background背景相关

    在CSS中 背景属性用于定义HTML元素的背景. background主要设置一下五个属性: background-color  // 设置元素的背景颜色. background-image // 把 ...

  5. 行为驱动:Cucumber + Selenium + Java(五) - 使用maven来实现cucumber测试和报告

    在上一篇中,我们介绍了Selenium + Cucumber + Java框架下的测试用例参数化/数据驱动,这一篇我们来使用maven去搭建cucumber框架以及实现测试报告. 5.1 为什么要用m ...

  6. jquery快速入门(四)

    jQuery 遍历 向上遍历 DOM 树 parent() parent() 方法返回被选元素的直接父元素.该方法只会向上一级对 DOM 树进行遍历. parents() parents() 方法返回 ...

  7. SLAM+语音机器人DIY系列:(四)差分底盘设计——1.stm32主控硬件设计

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  8. C# 中 equals( ) 和 == 的区别和用法

    Equals: 下面的语句中,x.y 和 z 表示不为 null 的对象引用. * 除涉及浮点型的情况外,x.Equals(x) 都返回 true. * x.Equals(y) 返回与 y.Equal ...

  9. 在Linux上部署Web项目

    You believe it or not there is a feeling, lifetime all not lost to time. 在Linux上部署Web项目 这个是普通的web项目, ...

  10. Odoo:全球第一免费开源ERP库龄表的简单实现方法(无需二开)

    问题背景 希望查看库龄超过30天的货物,该如何实现?此种简单数据查询需要二开吗? 解决方案 方法一:Stock Quant列表视图增加过滤器 <filter string="库龄超30 ...