• LintCode 汉诺塔


    题目链接: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 ightarrow2^{n - 1} - 1$依次模拟每个大步,如果 i 的最低 2 进制位的位置是偶数位置时,就执行 2 次操作 3,否则执行 1 次操作 1 和 1 次操作 2。

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

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

    代码如下

     1 class Solution {
     2 public:
     3     string L = "A", M = "B", R = "C";
     4     vector< string > ans;
     5     /**
     6      * @param n: the number of disks
     7      * @return: the order of moves
     8      */
     9     vector<string> towerOfHanoi(int n) {
    10         if(n % 2 == 0) swap(M, R);
    11         ans.push_back(step(L, R));
    12         
    13         n = (((1 << n) - 2) >> 1);
    14         for(int i = 1; i <= n; ++i) {
    15             // 如果i的最低2进制位的位置是偶数,就执行2次操作3,否则执行1次操作1和一次操作2
    16             if(__builtin_ffs(i) % 2 == 0) {
    17                 op3();
    18                 op3();
    19             }
    20             else {
    21                 op1();
    22                 op2();
    23             }
    24         }
    25         
    26         return ans;
    27     }
    28     
    29     inline string step(string x, string y) {
    30         return "from " + x + " to " + y;
    31     }
    32     
    33     inline void op1() {
    34         swap(M, R); 
    35         ans.push_back(step(L, R));
    36     }
    37     
    38     inline void op2() {
    39         swap(L, M);
    40         ans.push_back(step(L, R));
    41     }
    42     
    43     inline void op3() {
    44         swap(M, L); swap(R, M); 
    45         ans.push_back(step(L, R));
    46     }
    47 };
    View Code
  • 相关阅读:
    leetcode 第二题Add Two Numbers java
    二叉树中的那些常见的面试题(转)
    运行的指令
    Python常见经典 python中if __name__ == '__main__': 的解析
    软件测试基本概念
    JAVA Android王牌教程
    17个新手常见Python运行时错误
    QTP
    链表有关的常见面试题
    Robot Framework and Ride
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/11341166.html
Copyright © 2020-2023  润新知