http://acm.hdu.edu.cn/showproblem.php?pid=1995
汉诺塔5:
解析:
1.首先,k 号盘子的移动次数只与 k 下面的盘子数有关,而与 k 上面的盘子数无关,因为这样可以找规律,所以,原问题就可以转化为这样:
给定 k 个盘子,最上方的盘子移动了多少次。
2.找规律:假设最上方的盘子编号为 1 。
k==1,移动 1 次 ;
k==2,1 移动 2次,
2 移动 1 次;
k==3,1 移动 4 次;
2 移动 2 次;
3 移动 1 次;
递推表达:
1 /* */ 2 # include <bits/stdc++.h> 3 #include<cstdio> 4 #include<iostream> 5 using namespace std; 6 int main() 7 { 8 long long a[61]={0}; 9 int i; 10 int t; 11 int n,k; 12 for(a[0]=i=1;i<60;i++) 13 { 14 a[i]=a[i-1]*2; 15 } 16 scanf("%d",&t); 17 while(t--) 18 { 19 scanf("%d %d",&n,&k); 20 printf("%lld ",a[n-k]); 21 } 22 return 0; 23 }
递归表达:(超时了)
1 /* */ 2 #include<stdio.h> 3 long long int f(int n,int k) 4 { 5 if(k==n) return 1; 6 else return f(n,k+1)*2; 7 } 8 int main() 9 { 10 int T,n,k,i; 11 while(~scanf("%d",&T)) 12 { 13 for(i=0; i<T; i++) 14 { 15 scanf("%d %d",&n,&k); 16 printf("%lld ",f(n,k)); 17 } 18 } 19 return 0; 20 }