# Hanoi Tower Sequence

Total Submit : 841    Accepted Submit : 212

# Problem

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.

4
1
4
100
100000000000000

Case 1: 1

Case 2: 3

Case 3: 3

Case 4: 15

# Problem Source

ZSUACM Team Member

==================================我是华丽的分割线==============================

分析：

// By Rappizit@2007-09-11

#include
<cstdio>
#include
<cstring>
using namespace std;

const int DIGIT = 9;        // 大整数的进制为 10^DIGIT（大整数每个单元相当 DIGIT 个十进制数字）
const long long BitBase = 10;
const long long UnitBase = 1000000000;
const long long BASE [10= {110100100010000100000

1000000100000001000000001000000000}
;
const int SHBITS = 18;
const long long POW2 = 262144;    //1 << 18;
const long long mask = 262143;    //(1 << 18) - 1;

const int N = 101;                // 输入的最大位数
char str [N + 1];                // 输入的字符串存放于 str []
long long vli [N / DIGIT + 1];        // 字符串转换成 10^9 进制的大整数的各个单元存放于 vli []

int len = 0;                // 输入的字符串长度（十进制大整数位数）
int unit = 0;                // 转成 10^9 进制的大整数的单元数

// 假设字符串 str 正确表示一个正整数，将该字符串转换成 10^9 进制的大整数，并存放到 vli []
void str2vli ()
{

int size = len;
unit
= (size + DIGIT - 1/ DIGIT;    // 大整数的单元数为 ceil (double (size) / DIGIT)
long long cx = 0;

int p = 0;                // 当前单元的下标
int i, j, k;

// 从字符串的最末位置开始，每 DIGIT 个字符作为一个 UNIT，最后可能剩下几个字符
for (i = size - 1, j = DIGIT - 1; i >= j; i -= DIGIT)

{
cx
= 0;

for (k = 0; k < DIGIT; k ++)

{
cx
+= BASE [k]  * (long long)(str [i - k] - '0');
}

vli [p
++= cx;
}

if (p < unit)

{

// 处理剩下的几个字符
for (k = 0, cx = 0; i >= 0; i --, k ++)

{
cx
+= BASE [k] * (long long)(str [i] - '0');
}

vli [p
++= cx;
}

}

// 假设大整数 vli > 0，计算 vli 能被 2 整除的次数
int times ()
{

int p = 0;    // 大整数 vli 能被 2 整除的次数
int size = unit;    // size 为 vli 的单元数

// 如果 size 为 1 那么直接用 2 来试除 vli，每除一次， p 增加 1
if (size == 1)

{

while ((vli [0& 1== 0)

{
p
++;
vli [
0>>= 1;
}

return p;
}

// 如果 vli 能被 POW2 整除则 vli /= POW2
while (((vli [0+ vli [1* UnitBase) & mask) == 0)    // vli % POW2 == 0
{
p
+= SHBITS;                // vli 能再多被 2 整除 SHBITS 次
long long r = 0;        // r 为上一个单元除以 POW2 的余数
for (int i = size - 1; i >= 0; i --)

{

long long dx = r * UnitBase + vli [i];
r
= dx & mask;            // r = dx % POW2
vli [i] = dx >> SHBITS;        // vli [i] = dx / POW2
}

if (vli [size - 1== 0)        // 最高位为 0，则 size 减少 1
{
size
--;
}

}

// 如果 vli 能被 2 整除则 vli /= 2
while ((vli [0& 1== 0)

{
p
++;

long long r = 0;

for (int i = size - 1; i >= 0; i --)

{

long long dx = r * UnitBase + vli [i];
r
= dx & 1;
vli [i]
= dx >> 1;
}

if (vli [size - 1== 0)

{
size
--;
}

}

return p;
}

int test ()
{
scanf (
"%s"&str);
len
= strlen (str);
str2vli ();

return times () + 1;
}

int main ()
{

int t;
scanf (
"%d"&t);

for (int i = 1; i < t; i ++)

{
printf (
"Case %d: %d ", i, test ());
}

printf (
"Case %d: %d ", t, test ());

return 0;
}

Run ID   User Name   Problem   Language   Status   Run Time   Run Memory   Submit Time
82506    rappizit  1028  C++  Accepted  0 sec  256 KB  2007-09-11 15:16:57

Rank   Submit Time   Run Time   Run Memory   Language   User

1   2005-12-10 01:15:14   0.00S   148K   C   wangqiang

2   2007-09-11 15:16:57   0.00S   256K   C++   rappizit

3   2006-12-22 00:02:44   0.00S   260K   C++   jackeyyang

4   2005-04-16 19:16:26   0.00S   264K   C++   Savior

5   2006-08-16 00:52:04   0.00S   264K   C++   cockerel

==================================我是华丽的分割线==============================

1 << k 即为 2k  ，a & ((1 << k ) - 1) 即为 a % 2k ，a >> k 即为 a / 2k

((vli [0] + vli [1] * UnitBase) & mask) == 0 ，其中 vli [0] + vli [1] * UnitBase 表示大整数的后 18 位十进制数字，UnitBase = 1,000,000,000 ，mask = (1 << 18 ) - 1 。

PS：这题是算法分析与设计课的第一次作业中的。之前没用109 进制来做，运行时间为 0.06S ， 换成109 进制 且使用位运算就为 0.03S ，然后把输入输出换成 scanf  ， printf 的就为 0.00S ！（cin ， cout 比较慢。）我稍微修改了一下代码然后用老师指定的 ID （csa+学号）再提交了一次，内存少用了 4K ，再次排在第二名，将原来的 ID rappizit 挤到第三名了，呵呵。。

• 本文已收录于以下专栏：

## Sicily 1028 Hanoi Tower Sequence

/* 【题目大意】 汉诺塔，将其移动的每一步的盘号列出作为序列，求第p步需要移动的盘的盘号 序列如下：1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1.... ...
• fqeunagn_II
• 2013年01月05日 21:18
• 1339

## python 汉诺塔问题(Tower of Hanoi Puzzle)

• And_w
• 2016年03月18日 21:46
• 636

## sicily 1028. Hanoi Tower Sequence

1028. Hanoi Tower Sequence Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Ha...
• yuhao199555
• 2015年05月25日 23:13
• 373

## Sicily 1028. Hanoi Tower Sequence

• q271736642
• 2013年10月05日 21:00
• 1029

## zoj 1239 Hanoi Tower Troubles Again!

。。。
• xinag578
• 2015年03月08日 19:44
• 498

## 汉诺塔(Tower of Hanoi)问题的求解——利用栈与递归

• cainv89
• 2016年05月22日 23:32
• 6629

## Hanoi Tower问题分析

• zinss26914
• 2013年08月07日 23:21
• 1951

## Codeforces_392B_Tower of Hanoi(记忆化搜索)

B. Tower of Hanoi time limit per test 1 second memory limit per test 256 megabytes input stand...
• u010770930
• 2014年02月26日 12:06
• 682

## [sicily online]1028. Hanoi Tower Sequence

Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Hanoi Tower is a famous...
• qiuchenl
• 2012年11月26日 20:43
• 2585

## TOJ4132 Hanoi tower 汉诺塔（递归入门）

• Mizersy
• 2017年12月16日 21:32
• 40

举报原因： 您举报文章：Sicily 解题: 1028 Hanoi Tower Sequence 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)