题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1207
四柱汉诺塔问题
当 r = (sqrt(8*n+1)-1)/2 时,
存在 count = (n-(r*r-r+2)/2)*(int)pow(2,r)+1 ,此时所需的步骤最少。
1 #include<stdio.h> 2 #include<math.h> 3 4 int main() 5 { 6 int n,r; 7 long long int count; 8 while(scanf("%d",&n)!=EOF) 9 { 10 r = (sqrt(8*n+1)-1)/2; 11 count = (n-(r*r-r+2)/2)*(int)pow(2,r)+1; 12 printf("%I64d\n",count); 13 } 14 return 0; 15 }
还有一种方法,模拟三柱汉诺塔问题
三柱汉诺塔的步骤是:
(1)把n-1个盘子移动到B柱上
(2)把第n个盘子移动到C柱上
(3)把n-1个盘子移动到C柱上
那么四柱汉诺塔的步骤为:
(1)把n-k个盘子移动到B柱上
(2)把k个盘子移动到C柱上
(3)把n-k个盘子移动到C柱上
一开始我以为k=2,所以得到的结果不是最小,那么应该用for循环从1到n都计算一遍找到能使结果最小的k值。
将k个盘子移动到C柱上的步骤就是三柱汉诺塔问题,题目已经给出最小步骤为2^k-1
而1和3步骤所需最小步数一样,那么Hanoi[n]=a[k]+2*a[n-k],a[k]=pow(2,k)-1。
注意该题的数据容易溢出,所以我定义数据类型为double
代码如下:
#include<stdio.h> #include<math.h> int main() { int n; double a[70],Hanoi[70],k1,k2; int i,j; for(i = 1;i <= 64;i++) a[i] = pow(2,i) - 1; Hanoi[1] = 1; for(i = 2;i <= 64;i++) { k1=a[i]; for(j = 1;j < i;j++) { k2 = a[j] + 2*Hanoi[i-j]; if(k1 > k2) k1 = k2; } Hanoi[i] = k1; } while(scanf("%d",&n)!=EOF) { printf("%.f\n",Hanoi[n]); } return 0; }