7-2 不一样的汉诺塔
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置若干金盘(如下图)。
游戏的目标
把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。
操作规则
每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
事实上,汉诺塔游戏中的行动可以这样看待:当你需要移动某个盘子的时候,你需要先将它上面的全部盘子移动到无关杆上,再将这个盘子移动到目标杆,然后将它上面的盘子从无关杆移动到目标杆。从而,这一问题就可以通过递归的方式解决了。现在题目给出起始杆上按规律码放的盘子数量,请你给出将它们移动到目标杆上所需的最少步数。
输入格式:
一个正整数N(N<5000),代表你需要移动的的盘子数。
输出格式:
一个正整数,代表最少需要的步数。
输入样例:
70
输出样例:
1180591620717411303423
提示:如遇WA,请注意输入数据的范围。
ac代码
#include<iostream>
#define N 5000
using namespace std;
// 执行快速幂运算(2^n)的函数
void qpow(int *num) {
int ans[N] = {0};
// 将每个数字乘以2
for (int i = 0; i < N; i++)
ans[i] = num[i] * 2;
// 处理进位
for (int i = 0; i < N; i++)
if (ans[i] >= 10) {
ans[i + 1] += ans[i] / 10;
ans[i] = ans[i] % 10;
}
// 用结果更新原始数组
for (int i = 0; i < N; i++)
num[i] = ans[i];
}
int main() {
int n;
cin >> n;
// 用初始值2初始化数组
int num[N] = {2};
// 进行n次快速幂运算
for (int i = 0; i < n - 1; i++)
qpow(num);
// 找到最高位的索引
int i = N - 1;
while (!num[i])
i--;
// 以相反的顺序打印结果
for (; i > 0; i--)
cout << num[i];
cout << num[0] - 1;
return 0;
}