[NOIP2007 普及组] Hanoi 双塔问题 题解

题目描述

给定 A、B、C 三根足够长的细柱,在 A 柱上放有 2n 个中间有孔的圆盘,共有 n 个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为 n=3的情形)。

现要将这些圆盘移到 C 柱上,在移动过程中可放在 B 柱上暂存。要求:

  1. 每次只能移动一个圆盘;
  2. A、B、C 三根细柱上的圆盘都要保持上小下大的顺序。

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

输入格式

一个正整数 nn,表示在 A 柱上放有 2n 个圆盘。

输出格式

一个正整数, 为完成上述任务所需的最少移动次数 AnAn​。

输入输出样例

输入 #1

1

输出 #1

2

其实这题非常水,找到规律,用高精度就行了。

我们可以先用深搜打表,设法找到ai与ai+1的关系。

深搜代码略……

n 1 2 3 4 5 ……

a 2 6 14 30 62 ……

其实,a[i]=a[i-1]+2^i;(这是列举众多规律众多一个,dalao勿喷)

a[0]=0;

下面是代码:

#include<cstdio>
using namespace std;
int l,n;
int a[201],b[201];//a是最终结果,b是2的i次方
void gjc()//高精乘,算2的i次方
{
    int t=0;
    for (int j=200;j>0;j--)
     {
         l=b[j]*2+t;
         b[j]=l%10;
         t=l/10;
     }
}
void gjj()//高精加,把数组B的值加到A里面
{
    int t=0;
    for (int j=200;j>0;j--)
     {
         l=a[j]+b[j]+t;
         a[j]=l%10;
         t=l/10;
     }
}
int main()
{
    //freopen("hanoi.in","r",stdin);
    //freopen("hanoi.out","w",stdout);
    scanf("%d",&n);//读入
    b[200]=1;//初值,不能漏掉
    for (int i=1;i<=n;i++)
     {gjc();gjj();}//运算
    int k=1;
    while (a[k]==0&&k<200)//去除前导0
     k++;
    for (int i=k;i<=200;i++)
     printf("%d",a[i]);//输出
    //fclose(stdin);
    //fclose(stdout);
}

在百忙之中写一篇题解也比较辛苦,写的这么长,麻烦拿拿你们皇帝般的纤纤玉手帮我点点赞吧。!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值