2015 年 JXNU_ACS 算法组寒假第一次周赛 1007 汉诺塔问题

汉诺塔问题

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 54   Accepted Submission(s) : 12
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

Problem Description

汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
不过现在有2*n个圆盘,柱子还是三根,圆盘有n种不同的尺寸,每一种尺寸的圆盘有两个,如通常那样,在第一根柱子上从下往上按照大小顺序摞着2*n个圆盘。要求每次只能移动一个圆盘,且不能把较大的圆盘放在较小的上面,显然,圆盘可以放在同样大的圆盘上面。如果相同尺寸的圆盘是相互不可区分的,要把一个双重塔从第一根桩柱移动到第三根桩柱最少需要移动多少次?如下图,为n=3时,即第一根柱子上有2*3个圆盘的初始状态。本图片由小KD友情提供!

Input

第一行是一个整数T,表示有T组测试数据
每组测试数据有一个正整数n(1<=n<=60),表示有2*n个圆盘。

Output

对于每组输入数据,输出最少要移动的次数。

Sample Input

2
1
2

Sample Output

2
6

Author

JXNU_WY 

简单的汉诺塔问题。
首先,为了方便描述,将三根柱子分别编号为A,B,C,A柱子上的盘子号从上往下依次编号为1,1,2,,,n,n.现在的任务就是要把A柱子上的2*n个盘子搬到C柱子上去,而且在搬的过程中,不能出现有大盘子在小盘子上面的情况。以f(n)表示把A柱子上的2*n个盘子搬到C柱子上去需要的次数。
当n=1时:显然此时f(1)=2;
当n=2时:先把A柱子上面的两个移到B柱子上,需要f(1)步,然后把A柱子上的底下两个移到C柱子上,需要f(1)步,最后把B柱子上的两个盘子移到C柱子上。需要f(1)步,共3*f(1)步,总得来说,可以叙述成,A柱子上的4个盘子借助B柱移动到C柱子上需要步3*f(1),故此时有f(2)=6;
当n>4时:先把A柱子上的1,1,2,,,n-1,n-1号借助C柱移到B柱子,需要f(n-1)步,然后把A柱子上的两个n号移动到C柱子上,需要f(1)步,最后把B柱子上的1,1,2,,,,n-1,n-1号借助A柱移动到C柱子上,共需f(n-1)+f(1)+f(n-1),即f(n)=2*f(n-1)+f(1)


综上:有f(n)=2*f(n-1)+f(1),n>=1,其中f(1)=2;
易得f(n)=2^(n+1)-2
下面是C++的参考代码
#include<iostream>
#include<fstream>
#define LL long long
using namespace std;
int main()
{
    int t;
    LL n;
    cin.sync_with_stdio(false);
    cin>>t;
    while(t--)
    {
        cin>>n;
        cout<<(((LL)1<<(n+1))-2)<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值