Hanoi Tower Sequence

Hanoi Tower Sequence

一、问题描述

Description

Hanoi Tower is a famous game invented by the French mathematician Edourard Lucas in 1883. We are given a tower of n disks, initially stacked in decreasing size on one of three pegs. The objective is to transfer the entire tower to one of the other pegs, moving only one disk at a time and never moving a larger one onto a smaller.

The best way to tackle this problem is well known: We first transfer the n-1 smallest to a different peg (by recursion), then move the largest, and finally transfer the n-1 smallest back onto the largest. For example, Fig 1 shows the steps of moving 3 disks from peg 1 to peg 3.

Now we can get a sequence which consists of the red numbers of Fig 1: 1, 2, 1, 3, 1, 2, 1. The ith element of the sequence means the label of the disk that is moved in the ith step. When n = 4, we get a longer sequence: 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1. Obviously, the larger n is, the longer this sequence will be.
Given an integer p, your task is to find out the pth element of this sequence.

Input
The first line of the input file is T, the number of test cases.
Each test case contains one integer p (1<=p<10^100).

Output
Output the pth element of the sequence in a single line. See the sample for the output format.
Print a blank line between the test cases.


Sample Input
4
1
4
100
100000000000000

 

Sample Output
Case 1: 1
 
Case 2: 3
 
Case 3: 3
 
Case 4: 15

二、问题分析

对于Hanoi Tower问题我们已经非常熟悉,此题的关键是找出盘子移动序列的规律,那么怎么找出其规律呢?下面重点介绍怎么找出这个规律。

首先求出盘子移动序列的递归表达式,令S(n)为有n个盘子时的盘子移动序列,那么有下列的表格


从表格上我们很容易看出S(n)与S(n-1)之间的递推关系:S(n)=S(n-1) n S(n-1) (1)

由关系(1)我们很容易看出当盘子数量为n时:S(n)的长度为L(n)=L(n-1)+1+L(n-1)=2L(n-1))+1 (2)

由关系(2)我们得出当盘子数量为n时,序列长度为:L(n)=2^n-1;(3)(递推关系(2)推出关系(3)的过程可以由(2)构造等比数列求出)

另外,更重要的是我们可以由递推关系(1)发现,盘子移动序列其实是一个满二叉树的中序遍历序列,给出下面的示例图(这里我们以4个盘子为例),大家就可以很清楚的看出来。


这就是说,每个号码的盘子都只是在二叉树的同一层出现,问题归结为:由给出的第p步移动,我们只需要知道该步位于二叉树的哪一层,然后输出相应的盘子号码即可。

好了,到此,问题归结为找出每一个号码的盘子都在序列中哪些位置出现。根据上图,我们可以找到下列规律:

1出现的位置为:1            3               5             7        ...

2出现的位置为:2            6              10            14        ...

3出现的位置为:4           12              20            28        ...

k出现的位置为:2^(k-1)  2^(k-1)+2^k  2^(k-1)+2*2^k  2^(n-1)+3*2^k  ...

所以盘子k出现的位置为:2^(k-1)+(n-1)*2^k,即:序列的第2^(k-1)+(n-1)*2^k=(2n-1)*2^(k-1)(n=1,2,3,...)个位置的数字是k。

最后,对于任意给定的p,我们求出位置p所在二叉树中的层数(也可以说是二叉树中序遍历中第p步访问的具体结点位置,当然,由于每一层中所有结点盘号均相同,所以只需找出层数),问题解决。

三、问题解决

对于给定的位置p,我们令(2n-1)*2^(k-1)=p。求出相应的k即可,但是这里的n怎么办呢?前面已经提到,n只是影响到了二叉树中同一层结点位置,因此在求p值的时候可以忽略掉系数(2n-1),即令2^(k-1)=p即可,这样对于p,我们只用求出p能被2整除的次数,然后加1即可得到k。到此,问题解决。至于程序,大家可以在网上找,一大把。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值