题目链接:https://www.lintcode.com/problem/tower-of-hanoi/description

题目大意

  经典递归问题。

分析

  由于是经典问题了,这里不讨论用递归实现,也不讨论用栈模拟实现,只讨论纯迭代实现。
  首先用 L, M, R 来标记左柱子,中柱子,右柱子。
  我们知道汉诺塔问题与二进制是密不可分的,“n-圆盘汉诺塔问题”最少只需要$2^n - 1$步,而且如果 n 为奇数,第一步必然是 L->R;如果 n 为偶数,第一步必然是 L->M。
  现在我们定义三个操作,每个操作相当于走一步:
  1. 把 M 标记和 R 标记互换,执行 L->R。
  2. 把 L 标记和 M 标记互换,执行 L->R。
  3. 把 L 标记和 M 标记互换,把 M 标记和 R 标记互换,执行 L->R。

  于是这个问题可以这样解决,去掉第一步,还剩$2^n - 2$步,如果我们把走两步算作一大步,那么还剩$2^{n - 1} - 1$大步,我们令$i:1\rightarrow2^{n - 1} - 1$依次模拟每个大步,如果 i 的最低 2 进制位的位置是偶数位置时,就执行 2 次操作 3,否则执行 1 次操作 1 和 1 次操作 2。

  神奇的是,这样做居然是可行的。

  PS:我是不知道为啥,我是闲着无聊找规律找到的。

代码如下

 class Solution {
public:
string L = "A", M = "B", R = "C";
vector< string > ans;
/**
* @param n: the number of disks
* @return: the order of moves
*/
vector<string> towerOfHanoi(int n) {
if(n % == ) swap(M, R);
ans.push_back(step(L, R)); n = ((( << n) - ) >> );
for(int i = ; i <= n; ++i) {
// 如果i的最低2进制位的位置是偶数,就执行2次操作3,否则执行1次操作1和一次操作2
if(__builtin_ffs(i) % == ) {
op3();
op3();
}
else {
op1();
op2();
}
} return ans;
} inline string step(string x, string y) {
return "from " + x + " to " + y;
} inline void op1() {
swap(M, R);
ans.push_back(step(L, R));
} inline void op2() {
swap(L, M);
ans.push_back(step(L, R));
} inline void op3() {
swap(M, L); swap(R, M);
ans.push_back(step(L, R));
}
};

LintCode 汉诺塔的更多相关文章

  1. 【LintCode·容易】用栈模拟汉诺塔问题

    用栈模拟汉诺塔问题 描述 在经典的汉诺塔问题中,有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子.要求盘子必须按照从小到大的顺序从上往下堆 (如:任意一个盘子,其必须堆在比它大的盘子上面).同时, ...

  2. 算法笔记_013:汉诺塔问题(Java递归法和非递归法)

    目录 1 问题描述 2 解决方案  2.1 递归法 2.2 非递归法 1 问题描述 Simulate the movement of the Towers of Hanoi Puzzle; Bonus ...

  3. C#递归解决汉诺塔问题(Hanoi)

    using System;using System.Collections.Generic;using System.Linq;using System.Text; namespace MyExamp ...

  4. 数据结构0103汉诺塔&八皇后

    主要是从汉诺塔及八皇后问题体会递归算法. 汉诺塔: #include <stdio.h> void move(int n, char x,char y, char z){ if(1==n) ...

  5. Conquer and Divide经典例子之汉诺塔问题

    递归是许多经典算法的backbone, 是一种常用的高效的编程策略.简单的几行代码就能把一团遭的问题迎刃而解.这篇博客主要通过解决汉诺塔问题来理解递归的精髓. 汉诺塔问题简介: 在印度,有这么一个古老 ...

  6. 几年前做家教写的C教程(之四专讲了指针与汉诺塔问题)

    C语言学习宝典(4) 指针:可以有效的表示复杂的数据结构,能动态的分配动态空间,方便的使用字符串,有效的使用数组,能直接处理内存单元 不掌握指针就没有掌握C语言的精华 地址:系统为每一个变量分配一个内 ...

  7. python实现汉诺塔

    经典递归算法汉诺塔分析: 当A柱子只有1个盘子,直接A --> C 当A柱子上有3个盘子,A上第一个盘子 --> B, A上最后一个盘子 --> C, B上所有盘子(1个) --&g ...

  8. fzu1036四塔问题(汉诺塔问题拓展)

    #include<iostream> #include<cstdio> #include<cmath> using namespace std; ]; int ru ...

  9. 1019: [SHOI2008]汉诺塔

    1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1495  Solved: 916[Submit][Status] ...

随机推荐

  1. div绝对居中、宽高自适应、多栏宽度自适应

    <style> body { background-color: #e1ddd9; font-size: 12px; font-family: Verdana, Arial, Helvet ...

  2. JS-ValidForm:介绍

    ylbtech-JS-ValidForm:介绍 1.返回顶部 1. 关于Validform Validform:一行代码搞定整站的表单验证! 1 $(".demoform").Va ...

  3. java获取字符串编码和转换字符串编码

    public class EncodingUtil { // 这里可以提供更多地编码格式,另外由于部分编码格式是一致的所以会返回 第一个匹配的编码格式 GBK 和 GB2312 public stat ...

  4. centos安装virtualbox

    参考:http://www.if-not-true-then-false.com/2010/install-virtualbox-with-yum-on-fedora-centos-red-hat-r ...

  5. Cocos2d-x的Android配置以及相关参考文档

    关于Win7下配置Coco2d-x的Android开发环境,可以参考子龙山人的博客:Setting Up Cocos2d-x Android Development on Win7,这篇文章写得很详细 ...

  6. MYSQL索引的深入学习

    通常大型网站单日就可能会产生几十万甚至几百万的数据,对于没有索引的表,单表查询可能几十万数据就是瓶颈. 一个简单的对比测试 以我去年测试的数据作为一个简单示例,20多条数据源随机生成200万条数据,平 ...

  7. python3中浮点数相减问题(大部分时候只需要关注整数的二进制形式就行了)

    首先直接上判断方法:一切判断直接将整数部分装化成二进制,如果位数相等则相减后的值是等于的,如果不相等,相减大的结果一定不等于你要比较的结果. 如66.6-60.6==6.0的情况,66.6的二进制:1 ...

  8. USACO Wifi Setup /// 贪心

    题目大意: 若在x处防止一个覆盖范围为r的wifi基站 可以覆盖 x-r 到 x+r 范围 花费为 A+B*r 给定n 给定n个奶牛的位置 求覆盖所有奶牛的最小费用 (可设置任意多个wifi基站) 贪 ...

  9. zabbix-Graphs

    图形 概述 随着大量的监控数据被采集到Zabbix中,如果用户可以以可视化的表现形式来查看发生了什么事情,那么和仅仅只有数字的表现形式比起来则更加轻松. 以下是进行图形设置的地方.图形可以一目了然地掌 ...

  10. 使用Hbuilder 报错The keyword 'export' is reserved

    右击文件 > 验证本文档语法(V)后报错 解决: 项目右键->”属性”->”语法&框架”界面中配置项目的javaScript版本,将ECMAScript5.1 修改为6.