描述
给定$A$、$B$、$C$三根足够长的细柱,在$A$柱上放有$2n$个中间有孔的圆盘,共有$n$个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为$n=3$的情形)。
现要将这些圆盘移到$C$柱上,在移动过程中可放在$B$柱上暂存。要求:
(1)每次只能移动一个圆盘;
(2)$A$、$B$、$C$三根细柱上的圆盘都要保持上小下大的顺序;
任务:设$A_n$为$2_n$个圆盘完成上述任务所需的最少移动次数,对于输入的$n$,输出$A_n$。
输入格式:
一个正整数$n$,表示在$A$柱上放有$2n$个圆盘。
输出格式:
一个正整数, 为完成上述任务所需的最少移动次数$A_n$。
样例输入:
2
样例输入:
6
算法分析
首先我们知道如果是单个盘子,设$n$个盘子所需步数为$F(n)$ 则$F(n)=2*F(n-1)+1$
然而这道题是双盘,所以相当于把单盘移动次数乘2。
我们可以得出单盘的通项公式为$2^p-1$;
所以双盘的通项公式为$2^{p+1}-2$
这道题数据范围贼大,所以我们需要高精度
1 //Hanoi双塔问题.cpp 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 int a[100010]; 6 int main(){ 7 int n; 8 cin>>n; 9 int j=1; 10 int k=1; 11 memset(a,-1,sizeof(a)); 12 a[1]=1; 13 for(int i=1;i<=n+1;i++){ 14 while(a[j]>=0){ 15 a[j]*=2; 16 j++; 17 } 18 while(a[k]>=0){ 19 if(a[k]>=10){ 20 a[k]%=10; 21 if(a[k+1]<0){ 22 a[k+1]=0; 23 a[k+1]++; 24 break; 25 } 26 else{ 27 a[k+1]++; 28 } 29 } 30 k++; 31 } 32 j=1;k=1; 33 } 34 int y=0; 35 a[1]-=2; 36 for(int i=1;i<=100000;i++){ 37 if(a[i]>=0){ 38 y++; 39 } 40 } 41 for(int i=y;i>=1;i--){ 42 cout<<a[i]; 43 } 44 }