您的位置:首页 > 其它

10.30 H - 汉诺塔IV

2016-10-31 12:34 204 查看
                                                              H - 汉诺塔IV

Problem Description

还记得汉诺塔III吗?他的规则是这样的:不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到小盘的上面。xhd在想如果我们允许最大的盘子放到最上面会怎么样呢?(只允许最大的放在最上面)当然最后需要的结果是盘子从小到大排在最右边。

 

Input

输入数据的第一行是一个数据T,表示有T组数据。

每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。

 

Output

对于每组输入数据,最少需要的摆放次数。

 

Sample Input

2 1 10

 

Sample Output

2 19684

 

Author

xhd

 

Source

ACM程序设计期末考试_热身赛(感谢
xhd & 8600)

 

Recommend

lcy

训练赛时候遇到的题

做过汉诺塔3的话,可以直接得到一个结论,n个盘子从最左杆移到最右杆是3^n-1次,因为左右等效,实际上左杆到中间杆与右杆到中间杆的次数即(3^n-1)/2次;

我还是从数学角度分析:

首先右侧n个盘子从右到中间需要次数为a
;然后第n+1个盘子从最左端到最右端只需两次,然后再将n个盘子由中间杆移到右杆,次数也为a


可列两式:

1.a
=(3^n-1)/2

2.b
(总次数)=a[i-1]*2+2

解出函数式:b
=3^(n-1)+1

以下给出通项公式代码:

#include<iostream>
#include<cmath>
#include<stdio.h>
using namespace std;
int main()
{
int n,a;
while(~scanf("%d",&n)&&n)
{
while(n--)
{
scanf("%d",&a);
long long int step=1;
if(a==1) cout<<"2"<<endl;
else
{
for(int i=1;i<a;i++)
step*=3;
step+=1;
cout<<step<<endl;
}
}
}
return 0;
}


若是没有做过汉诺塔3的话

想法可以如下:

设a
为一杆移动到间隔杆的次数;b
是移动到相邻杆的次数;c
是总次数;

则有a[i]=3*a[i-1]+1+1    ---(1)

       c[i]=2*b[i]+a[i]+2     ---(2)

       b[i]=b[i-1]+a[i-1]+1  ---(3)

本质还是相同的。

如何正确的找到递推的关系便是解决这类题目的关键!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: