题目描述
给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有空的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为n=3的情形)。现要将 这些国盘移到C柱上,在移动过程中可放在B柱上暂存。要求:
(1)每次只能移动一个圆盘;
(2) A、B、C三根细柱上的圆盘都要保持上小下大的顺序;
任务:设An为2n个圆盘完成上述任务所需的最少移动次数,对于输入的n,输出An。
输入
一个正整数n,表示在A柱上放有2n个圆盘。
输出
仅一行,包含一个正整数,为完成上述任务所需的最少移动次数An。
样例输入
Sample Input1:
1
Sample Input2:
2
样例输出
Sample Output1:
2
Sample Output2:
6
数据范围限制
【限制】
对于50%的数据, 1<=n<=25
对于100% 数据, 1<=n<=200
提示
【提示】 设法建立An与An-1的递推关系式。
Solution
设f[i]表示A柱放2*i个圆盘的最少移动步数,则有
f[i]=f[i-1]*2+2
其中f[1]=2,上式子的含义是,先把除了当前最大的两个盘子的其他盘子(即2*(i-1)个盘子的最少移动步数)移动到B柱,然后把最大的两个盘子移动到C柱,最后再把2*(i-1)个盘子移动到C柱。
注意2^200要用高精度。
Code
#include<cstdio>
#define M 1000000
using namespace std;
int n,f[210];
int getlen(int x){
int l=0;
while(x){x/=10;l++;}
return l;
}
int main(){
freopen("hanoi.in","r",stdin);
freopen("hanoi.out","w",stdout);
scanf("%d",&n);
f[1]=2;f[0]=1;
for(int i=2;i<=n;i++){
for(int j=1;j<=f[0];j++) f[j]*=2;
f[1]+=2;
for(int j=1;j<=f[0];j++){
f[j+1]+=f[j]/M;
f[j]%=M;
}
while(f[f[0]+1]>0) f[0]++;
}
printf("%d",f[f[0]]);
for(int i=f[0]-1;i>0;i--){
for(int j=1;j<=6-getlen(f[i]);j++) printf("0");
if(f[i]) printf("%d",f[i]);
}
return 0;
}
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/86602273