HDU 汉诺塔 1207 2064 2077 1995
来源:互联网 发布:什么是软件系统 编辑:程序博客网 时间:2024/05/19 09:38
汉诺塔II
题目
点击打开链接1207
分析
现在有四根柱子(A,B,C,D),其他规则不变。我们的目标是将n个盘移到D上,所以我们首先将n-1个盘移到B、C上,然后将第n个盘移到D上。我们令从A->D需要F(n)步,下面分为三步实现:
- 将r个柱子从A->B,共有F(r)步;
- 将剩下的n-r个柱子从A-D,此时,B柱上所有的盘子都比这n-r个盘子小,所以只能使用C、D,这是一个经典的汉诺塔问题。需要2^(n-r)-1步
- 再将B柱上的r个盘子移到D上,需要F(r)步
所以一共需要F(n) = 2*F(r) + 2^(n-r) - 1步。对于不同的r,F(n)不同。我们采用循环的方式,对r进行遍历,用min标记F(n)最小值。求得min[ 2*F(r) + 2^(n-r) - 1] (1 <= r < n)
代码
#include <stdio.h>#include <math.h>#define MAX 70 #define INF 99999999long long hanoi2(int);int main(){ int n; long long res; while (scanf("%d", &n) != EOF) { if (n < 1 || n > 64) break; res = hanoi2(n); printf("%lld\n", res); } return 0;}long long hanoi2(int n){ long long a[MAX] = { 0, 1, 3 }; long long min; int i, j; for (i = 3; i <= n; i++) { min = INF; //作为哨兵,初始化应该放在第一个循环内,这样第二个循环才能顺利执 for (j = 1; j < i; j++) { /* 一定要转换为unsigned,否则当n=64时,结果会溢出 */ if(min > 2*a[j] + (unsigned long long )pow(2, i-j) - 1) min = 2*a[j] + (unsigned long long )pow(2,i-j) - 1; } a[i] = min; } return a[n]; }
汉诺塔III
题目
点击打开链接 2064
分析
这道题很简单。我们令将n个盘从A->B需要F(n)步。下面分三步进行:
- 将n-1个盘从A-B-C,需要F(n-1)步
- 将第n个盘从A-B,再将n-1个盘从C-B-A,需要F(n-1) + 1 步
- 将第n个盘从B-C,再将n-1个盘从A-B-C,需要1 + F(n-1) 步
所以F(n) = 3*F(n-1) + 2步,有通项公式 f(n) = 3^n - 1
代码
int main(){int n, i;long long res;while (scanf("%d", &n) != EOF){if (n < 1 || n > 35)break;res = 2;if (n == 1)printf("%lld\n", res);else{for (i = 2; i <= n; i++){res = 3*res + 2;}printf("%lld\n", res);}}return 0;}
汉诺塔IV
题目
点击打开 2077
分析
这道题是2064汉诺塔3的变形。我们分三步实现:
- 先将上面n-1个盘子从A-B,需要g(n-1)步
- 再将第n个盘子从A-B-C,需要2步
- 最后将n-1个盘子从B-C,需要g(n-1)步
F(n) = 2 * g(n-1) + 2.所以题目转化为只要求g(n)的递推式,或者通项公式即可。
为了实现1,我们需要将上面n-2个盘子从A-B-C(这就是汉诺塔3的问题),再将第n-1个盘子从A-B。然后,再将上面n-2个盘子从C-B。有,g(n-1) = 3^(n-2)-1 + 1 + g(n-2) ,从而有g(n) = (3^n - 1)/2。
所以,F(n) = 3^(n-1) + 1
代码
#include <stdio.h>#include <math.h>int main(){int n, t;long long res, temp;while (scanf("%d", &t) != EOF){while(t--){scanf("%d", &n);if (n < 1 || n > 20)break;res = (long long) pow (3, n - 1) + 1;printf("%lld\n", res);}}return 0;}
汉诺塔V
题目
点击打开1995
分析
这道题最水了。不要被表面假象所唬住。
假设有64个盘子,我们先看第64个盘子,它只需要移动1次;第63个盘子移动两次,前一次是为地64个盘子移的;第62个盘子移动4次,前两次是为第64个盘子移的,第三次是为了第63个盘子移的;。。。
可以看出规律第k个盘子移动了 2^(n-k)次。
代码
#include <stdio.h>#include <math.h>int main(){int t, n, k;long long res;while (scanf("%d", &t) != EOF){while (t--){scanf("%d %d", &n, &k);if ( k >= 1 && k <= n && n <= 60){res = (long long) pow (2, n-k);printf("%lld\n", res);}}}return 0;}
- HDU 汉诺塔 1207 2064 2077 1995
- 【DP】HDU-1207 2064 2077 汉诺塔专题
- HDU 2064 汉诺塔III 和 HDU 2077 汉诺塔IV
- HDU 1995 汉诺塔V && HDU 1996 汉诺塔VI &&HDU 2077 汉诺塔IV【快速幂】
- 汉诺塔问题及变形HDU 1207、2064、2077
- hdu 2077 汉诺塔IV
- hdu 2077 汉诺塔 IV
- HDU 2077 汉诺塔IV
- HDU 2077 汉诺塔IV
- HDU 2077 汉诺塔IV
- hdu 2077汉诺塔IV
- HDU 2077 汉诺塔IV
- HDU 2077 汉诺塔IV
- hdu 2077 汉诺塔IV
- hdu 2077 汉诺塔IV
- HDU 2077汉诺塔IV
- HDU-2077-汉诺塔IV
- hdu 2077 汉诺塔IV
- 九大排序算法总结
- ibatis 如何打印SQL语句
- mybatis物理分页的实现(转)
- 你要是放弃,你就是个杯具
- 相关推荐
- HDU 汉诺塔 1207 2064 2077 1995
- DWR 调用函数异常
- (JAVA)IO流
- Eclipse 设置字体
- 完成端口
- Python自学2:Python函数定义
- ui5 清除controll的cache
- dos下运行junit、运行依赖jar文件的class
- 遇到数据问题时快来试试吧