luogu P1096 Hanoi双塔问题

来源:互联网 发布:读spring源码 编辑:程序博客网 时间:2024/06/05 21:56

题目描述
给定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。

输入输出样例
输入样例#1: 复制
【输入样例1】
1
【输入样例2】
2
输出样例#1:
【输出样例1】
2
【输出样例2】
6
说明
【限制】
对于50%的数据,1<=n<=25
对于100%的数据,1<=n<=200
【提示】
设法建立An与An-1的递推关系式。

题解:
对于汉诺塔问题,可以列举结果1,3,7,15……容易得出结论h(n)=2^n+1。
而双塔问题就是汉诺塔问题的引生,原理不变,结果应该是汉诺塔问题结果的两倍,即h(n)=2^(n+1)+2,可以先去了解汉诺塔问题。
但是这道题的难点并不在题目本身,而在于解题过程必须用到高精度。
高精度应当专门去了解原理。

下面贴上代码,代码讲得比较详细了:

#include<stdio.h>#include<string.h>#define MAX 100000void hanoi(int n);int h[MAX],digit=0;int main(void){    int n;    scanf("%d",&n);    h[1]=1;//初始化     hanoi(n);    for(int i=digit;i>0;i--)      printf("%d",h[i]);//逆序输出     printf("\n");    return 0;}void hanoi(int n)//实现h(n)=(h(n)*2)^(n+1)-2 {    for(int i=0;i<=n;i++)//h(n)=(h(n)*2)^(n+1)    {      int m=0;      for(int j=1;j<MAX;j++)//h(n)=h(n)*2      {          h[j]=h[j]*2+m;          m=h[j]/10;          h[j]%=10;      }    }    h[1]=h[1]-2;//第一位减2(逆序后为最后一位)    int i=1;    while(h[i]<0)//处理退位(减2)     {        h[i]=h[i]+10;        h[i+1]=h[i+1]-1;    }    for(int i=MAX;i>0;i--)     if(h[i])//算出结果位数      {        digit=i;        break;     }}