约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。
现在我们改变游戏的玩法,不允许直接从最左(右)边移到最右(左)边(每次移动一定是移到中间杆或从中间移出),也不允许大盘放到下盘的上面。
Daisy已经做过原来的汉诺塔问题和汉诺塔II,但碰到这个问题时,她想了很久都不能解决,现在请你帮助她。现在有N个圆盘,她至少多少次移动才能把这些圆盘从最左边移到最右边?
输入格式:
包含多组数据,每次输入一个N值(1<=N=35)。
输出格式:
对于每组数据,输出移动最小的次数。
输入样例:
在这里给出一组输入。例如:
1
3
12
输出样例:
在这里给出相应的输出。例如:
2
26
531440
思路:(经典汉诺
> 在这种情况下,考虑 K 个圆盘的移动情况。为了首先将初始时最下方最大的圆盘移动到第三根柱子上,我们首先需要将其上的 K-1 个圆盘移动到第三根柱子上,而这恰好等价于移动 K-1 个圆盘从第一根柱子到第三根柱子。当这一移动完成以后,第一根柱子仅剩余最大的圆盘,第二根柱子为空,第三根柱子按顺序摆放着 K-1 个圆盘。同
将最大的圆盘移动到此时没有任何圆盘的第二根柱子上,并再次将 K-1 个圆盘从第三根柱子移动到第一根柱子,此时需要移动的次数相当于 K-1 个圆盘从第一根柱子到第三根柱子所需的移动次数。
再将最大的圆盘移动到第三根柱子上。此时一柱为其余盘,二柱为空,三柱为最大盘。若移动 K 个圆盘从第一根柱子到第三根柱子需要 F[K] 次移动,那么综上所述 F[K] 的组成方式为:
先移动 K-1 个圆盘到第三根柱子需要 F[K-1]次移动,
再将最大的圆盘移动到中间柱子需要 1 次移动,
然后将 K-1 个圆盘从第三根柱子移动回第一根柱子同样需要 F[K-1]次移动,
接着移动最大的盘子到第三根柱子需要 1 次移动,
最后将 K-1 个圆盘也移动到第三根圆盘需要F[K-1]次移动,
这样 F[K] = 3 * F[K - 1] + 2。即从第一根柱子移动 K 个圆盘到第三根柱子,需要三次从第一根柱子移动 K-1 个圆盘到第三根柱子,外加两次对最大圆盘的移动。
若函数 F(x)返回移动 x 根子所需要的移动次数,那么其递归方式为 3*F(x-1) + 2。
同时要确定递归的出口。当 x 为 1 时,即移动一个盘子从第一根柱子移动到第三根柱子,其所需的移动次数是显而易见的,为 2。即当函数的参数为 1时直接返回 2。
AC代码:
#include<bits/stdc++.h>
using namespace std;
long long F(int num)
{
if(num == 1)
return 2;
else
return 3*F(num-1)+2;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
printf("%lld\n",F(n));
return 0;
}
以为这就完了?,接下来看看真-极简做法
思路:找 规 律
AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long int n;
while (scanf("%lld",&n)!=EOF)
{
long long int x=3;
for (int i=1;i<n;i++)
x = 3*x;
printf("%lld\n",x-1);
}
return 0;
}