b161: NOIP2007 4.Hanoi双塔问题

时间:2023-03-09 15:13:48
b161: NOIP2007 4.Hanoi双塔问题

zerojudge  汉诺塔?图片问度娘
b161: NOIP2007
4.Hanoi双塔问题

题目:

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

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

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

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

输入1  2

输出2  6

While not eof

首先
咱们先得搞懂汉诺塔。

汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

感谢百度百科!

我们先看1个黄金圆盘的情况:

设上面的盘为x。

  1. 1.    将x移动到C

我们先看2个黄金圆盘的情况:

设上面的盘为x,下面的为y。

1.将x移动到B

2.将y移动到C

3.将x移动到C

共3步。

一般地,设n个圆盘的汉诺塔问题,一共需要移动H(n)步。则H(2)=H(1)+1+H(1)=2*H(1)+1

所以 H(n)=H(n-1)*2+1

再来看汉诺双塔:(更据之前的规律自己先推测一下)

再来看代码:

 #include <iostream>

 using namespace std;

 int main(){

          int a[]={};

          int n;

          while(cin>>n){

                    for(int i=;i<;i++)a[i]=;//初始化

                    a[]=;

                    for(int i=;i<=n;i++){

                             for(int j=;j<;j++){//乘2

                                      a[j]*=;

                             }

                             for(int j=;j<;j++){//进位

                                      a[j+]=(a[j]/)+a[j+];

                                      a[j]=a[j]%;

                             }

                   }

                    a[]=a[]-;

                    int l=;

                    while(a[l]==) l--;

                    for(int i=l;i>=;i--){

                               cout<<a[i];

                    }

                    cout<<endl;

          }

          return ;

 }