题解 - Hanoi 双塔问题
原题链接
题面简述
给定 \(A\)、\(B\)、\(C\) 三根足够长的细柱,在 \(A\) 柱上放有 \(2n\) 个中间有孔的圆盘,共有 \(n\) 个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的。现要将这些圆盘移到 \(C\) 柱上,在移动过程中可放在 \(B\) 柱上暂存。要求:
-
每次只能移动一个圆盘;
-
\(A\)、\(B\)、\(C\) 三根细柱上的圆盘都要保持上小下大的顺序;
任务:设 \(A_n\) 为 \(2n\) 个圆盘完成上述任务所需的最少移动次数,对于输入的 \(n\),输出 \(A_n\) 。
思路
这个是双塔,其实和单塔是一样的(两个圆盘不加区分,可以叠加,你懂得)
使用公式: \(f[i] = (f[i - 1] + 1) \times 2\) 即可。
另外我们为了简化代码,还可以这样:
\[f[i] = (f[i - 1] + 1) \times 2 \\ \ \ = f[i - 1] * 2 + 2
\]
化简式子之后就可以乘完再加上,然后统一处理进位。
完整代码:
有点懒,没用结构体,就让数组下标从 \(1\) 开始,然后 \(ans[0]\) 代表位数。
#include <bits/stdc++.h>
using namespace std;
int ans[100001];
int main() {
int n;
cin >> n;
memset(ans, 0, sizeof(ans));
ans[0] = 1; // 位数
ans[1] = 2;
for (int i = 2; i <= n; ++i) {
for (int j = 1; j <= ans[0]; ++j) {
ans[j] *= 2;
}
ans[1] += 2;
for (int j = 1; j <= ans[0]; ++j) {
ans[j + 1] += ans[j] / 10;
ans[j] %= 10;
}
if (ans[ans[0] + 1] != 0) {
ans[0]++;
}
}
for (int i = ans[0]; i >= 1; --i) {
cout << ans[i];
}
}
Copyright littlefrog(2019)
所有权利保留。