【小韦同学@神犇营-my1053-汉诺塔II】
题目:
描述
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着 64 片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
现在小码猿开始玩汉诺塔游戏, 他放了 n 片黄金圆盘在第一根柱子上,从上到下依次编号为 1 到 n,1 号圆盘最小,n 号圆盘最大。小码猿移动第 i 号圆盘的时候需要花费 i 点体力。现在小码猿想把圆盘全部移动到第 2 根柱子上,移动过程中小码猿必须准守游戏规则。
现在小码猿想知道他完成游戏的最小移动次数和最少消耗的体力。
输入
输入一个正整数 n(1 ≤ n ≤ 60)表示黄金圆盘的个数
输出
一行输出 2 个数,表示最小移动次数和最小消耗的体力,中间用一个空格隔开。
输入样例1
2
输出样例1
3 4
输入样例2
3
输出样例2
7 11
题解:
/*********************************************************************
* 题目:神犇营-my1053-汉诺塔II
* 作者:小韦同学
* 邮箱:weichangying_wcy@163.com
* 题解
思路:
将n个盘子全部从一个柱子移动到另一个柱子,需要3个步骤:
假设有1 2 3 三根柱子,现在从1号移到2号
首先,将1号上边的n-1个盘子全部移动到3号柱子
然后,将1号柱子上剩下的第n个盘子移动到第2号柱子
最后,将3号柱子上的n-1个盘子全部移动到第2号柱子
假设将m个盘子从一个柱子移到另一个柱子所需的移动次数为f(m)
那么,为了移动n个盘子,我们移动了两次n-1个盘子,此外还将第n个
盘子移动了1次,因此
f(n) = f(n-1) + 1 + f(n-1) = 2 * f(n-1) + 1
同理,移动n个盘子所需的体力:
g(n) = g(n-1) + n + g(n-1) = 2 * g(n-1) + n
注意:
可以用结构体,将计算移动次数与移动所耗费的体力同时计算
*********************************************************************/
#include <bits/stdc++.h>
using namespace std;
struct Ans{
long long times, power;
Ans(int t, int p){
times = t, power = p;
}
};
Ans hanoi(int n){
// 递归边界,当盘子数为1时
if (n == 1){
return Ans(1, 1);
}
// 递归调用函数
Ans ans = hanoi(n - 1);
ans.times *= 2, ans.power *= 2;
ans.times++, ans.power += n;
return ans;
}
int main(){
int n;
cin >> n;
Ans ans = hanoi(n);
cout << ans.times << " " << ans.power << endl;
return 0;
}
我是小韦同学,企者不立,跨者不行,每天进步一点点。
欢迎大家多多交流,如果发现有错误,请多指正。有疑问的同学也可以留言评论或者发邮件。
邮箱:weichangying_wcy@163.com