HDU 汉诺塔III

汉诺塔III


Problem Description
约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。
现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。
Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边?


Input
包含多组数据,每次输入一个N值(1<=N=35)。


Output
对于每组数据,输出移动最小的次数。


Sample Input
1
3
12


Sample Output
2
26
531440


题解:
题中改变了原有的汉诺塔规则,而是每次必须经过中间的柱子,尽管有些许变化但是推到过程是一样的(现设有A,B,C三个柱子,以及标号为1-N的盘子),既然不能将编号为N的盘子移动到C上,那么就必须先移动N到B上,这样的话就先有N- 1个盘子在C上这个状态,然后在移动N到C上之前又要把N-1个盘子移动到A上,要达到最终目的的话,就要再把N-1个盘子移动到C上。
  上述过程就得到一个递推式 F[N]= 3 F[N-1]+ 2, 得到F[N]= 3^ N- 1*。

#include<bits/stdc++.h>
using namespace std; 
long long a[35]; 
void f(){
	a[1]=2;
	for(int i=2;i<=35;i++){
		a[i]=3*a[i-1]+2;
	//	a[i]=pow(3,i)-1;  精度有问题 
	}
	return ;
}
int main(){
	f();
	int n;
	while(scanf("%d",&n)!=EOF){
		printf("%llu\n",a[n]);
	}
	return 0;
} 

或者

#include <cstdio>
#include <cstdlib>
using namespace std;
 
int main()
{
    unsigned long long ti;
    int N;
    while( scanf( "%d", &N )!= EOF )
    {
        ti= 1;
        for( int i= 1; i<= N; ++i )
        {
            ti*= 3;
        }
        printf( "%llu\n", ti- 1 );
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/shf1730797676/article/details/89432301
今日推荐