P1096
[NOIP2007 普及组] Hanoi 双塔问题
题目描述
给定 A、B、C 三根足够长的细柱,在 A 柱上放有 \(2n\) 个中间有孔的圆盘,共有 \(n\) 个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为 \(n=3\) 的情形)。

现要将这些圆盘移到 C 柱上,在移动过程中可放在 B 柱上暂存。要求:
- 每次只能移动一个圆盘;
- A、B、C 三根细柱上的圆盘都要保持上小下大的顺序。
任务:设 \(A_n\) 为 \(2n\) 个圆盘完成上述任务所需的最少移动次数,对于输入的 \(n\),输出 \(A_n\)。
输入格式
一个正整数 \(n\),表示在 A 柱上放有 \(2n\) 个圆盘。
输出格式
一个正整数, 为完成上述任务所需的最少移动次数 \(A_n\)。
样例 #1
样例输入 #1
1
样例输出 #1
2
样例 #2
样例输入 #2
2
样例输出 #2
6
提示
【限制】
- 对于 \(50\%\) 的数据,\(1 \le n \le 25\);
- 对于 \(100\%\) 的数据,\(1 \le n \le 200\)。
【提示】
设法建立 \(A_n\) 与 \(A_{n-1}\) 的递推关系式。
代码如下
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int a[200];
memset(a,0,sizeof a);
a[0] = 2;
int t = 0; //最高位
for (int j = 0; j < n; j++) {
int k = 0;
//翻倍
for (int i = 0; i <= t; i++)
a[i] *= 2;
//进位
for (int i = 0; i <= t; i++) {
if (a[i] >= 10) {
a[i] %= 10;
a[i + 1]++;
if (i == t)
t++;
}
}
}
//最高位大于10 进位
if (a[t] >= 10) {
a[t] %= 10;
t++;
a[t] = 1;
}
//减去2
int t1 = 2;
if (a[0] >= 2) {
a[0] -= 2;
} else {
//找到大于1的最小位
int k = 1;
while (a[k] < 1) {
a[k] = 9;
k++;
}
a[k] -= 1;
//如果减去的是最高位且减去后最高位为0则最高位往后退一位
if(k==t&&a[k]==0){
t--;
}
}
for (int i = t; i >= 0; i--)
cout << a[i];
return 0;
}

浙公网安备 33010602011771号