C语言 hanoi双塔问题(移动次数递推)

给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有空的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为n=3的情形)。现要将 这些国盘移到C柱上,在移动过程中可放在B柱上暂存。要求:

提交

(1)每次只能移动一个圆盘;

(2) A、B、C三根细柱上的圆盘都要保持上小下大的顺序;

任务:设An为2n个圆盘完成上述任务所需的最少移动次数,对于输入的n,输出An。

输入
输入文件hanoi.in为一个正整数n,表示在A柱上放有2n个圆盘。

输出
输出文件hanoi.out仅一行,包含一个正整数,为完成上述任务所需的最少移动次数An。

样例输入 Copy
1
样例输出 Copy
2
提示
对于50%的数据, 1<=n<=25

对于100% 数据, 1<=n<=200

设法建立An与An-1的递推关系式。

#include
long long f(int n);

int main()
{
long long n;
while(scanf("%lld",&n)!=EOF)
{
printf("%lld\n",2*f(n));
}
return 0;
}

long long f(int n)
{
//long long t
if(n==1)
return 1;
else
return (2*(f(n-1)+1)-1);

}
常规方法用递归long long无法满足精读,考虑用高精度计算

//递推 2^(n+1)-2;
#include
#define maxn 100//最终输出结果的位数,最后的第200项大概有60位
int main()
{
int n;

while(scanf("%d",&n)!=EOF)

{
int i,k=0,j=0,jinwei=1;统计进位次数
int a[maxn]={0};a[0]=2;//第一项定义为2,求2的n+1次方
for(i=0; i { int flag=0,count=0;
for(j=0;j<=jinwei;j++)
{
a[j]=a[j]*2+flag;
flag=0;
if(a[j] >= 10)//判断十位数是否大于0
{ flag=a[j]/10;//进位
a[j]=a[j]%10;
}
if(a[jinwei]&&a[jinwei+1]==0) count=1;
else count =0;
}
jinwei+=count;
}
for(i=jinwei-1; i>=1; i–) printf("%d",a[i]);
printf("%d\n",a[0]-2); //将最后一位减2,2的(n+1)次方为2,4,6,8,减2不存在十位数变化。
}
return 0;
}

附上高精度计算2的n次方代码,转自https://blog.csdn.net/weixin_43727125/article/details/84201649
#include
#define maxn 32
int main()
{
int n,i,k=0,j=0,WS=1;
int a[maxn]={0};a[0]=1;
scanf("%d",&n);

for(i=1; i<=n; i++)//进行n次与2乘法
{  int flag=0,count=0;
    for(j=0;j<=WS;j++)//进行当前位数+1次乘法(如果有新进位便于进位)
    {
        a[j]=a[j]*2+flag;//该位数乘2,计算次数加一
        flag=0;
        if(a[j] >= 10)
        {   flag=a[j]/10;
           a[j]=a[j]%10;
        }
        if(a[WS]&&a[WS+1]==0) count=1;//当预留进位a[WS]发生进位并且前一位数是0时,进1位
        else count =0;
    }
    WS+=count;
}
for(i=WS-1; i>=0; i--) printf("%d",a[i]);

return 0;

}
n为 5时,一直计算至4次方十位大于零,flag=1,a[1]=0;count=1,WS=1;随后a[1]=20+1,进位为1,i=5时如上循环a[1]=12+1=3,再进一位输出3,以此类推。

你可能感兴趣的:(力扣)