HDU 2064 汉诺塔III 和 HDU 2077 汉诺塔IV

来源:互联网 发布:单片机hex文件下载 编辑:程序博客网 时间:2024/06/10 06:00

题目:

Description

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

Input

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

Output

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

Sample Input

1312

Sample Output

226531440

这个题目的递推式比较简单,f(n)=3f(n-1)+2

可以直接求出通项公式,f(n)=3^n-1,也可以用数组记录所有的答案。

代码:

#include<iostream>using namespace std;int main(){/*long long a = 0;for (int i = 1; i <= 35; i++){a = a * 3 + 2;cout << a << ",";}*/long long l[35] = { 2, 8, 26, 80, 242, 728, 2186, 6560, 19682, 59048, 177146, 531440, 1594322, 4782968, 14348906, 43046720, 129140162, 387420488, 1162261466, 3486784400, 10460353202, 31381059608, 94143178826, 282429536480, 847288609442, 2541865828328, 7625597484986, 22876792454960, 68630377364882, 205891132094648, 617673396283946, 1853020188851840, 5559060566555522, 16677181699666568, 50031545098999706 };int n;while (cin >> n)cout << l[n - 1] << endl;return 0;}

题目:

Description

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

Input

输入数据的第一行是一个数据T,表示有T组数据。 
每组数据有一个正整数n(1 <= n <= 20),表示有n个盘子。 

Output

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

Sample Input

2110

Sample Output

219684

这个题目就稍微有些技巧了。

首先考虑,在汉诺塔III中,把n个盘子全部移到中间需要多少步。

其实如果仔细的思考的话,可以发现,在汉诺塔III中,要把n个盘子全部移到右边,其实就是分2大步。

第一步,全部移到中间,第二步,全部移到右边。

而且显然他们的步数相等,所以都是f(n)=3^n-1的一半。

回到本题,整个过程分为3个部分。

一,把n-1个盘子移到中间,(3^(n-1)-1)/2步

二,把最大的盘子移到右边,2步。

三,把n-1个盘子移到右边,(3^(n-1)-1)/2步

一共3^(n-1)+1步。

代码:

#include<iostream>using namespace std;int main(){/*long long a = 2;for (int i = 1; i <= 20; i++){cout << a << ",";a = a * 3 - 2;}*/int l[20] = { 2, 4, 10, 28, 82, 244, 730, 2188, 6562, 19684, 59050, 177148, 531442, 1594324, 4782970, 14348908, 43046722, 129140164, 387420490, 1162261468 };int t, n;cin >> t;while (t--){cin >> n;cout << l[n - 1] << endl;}return 0;}

1 0
原创粉丝点击