问题描述
有三根柱子 A B C ,A柱上有 n n n 个圆盘,最大的一个在底下,其余一个比一个小,依次叠上去。将所有在 A 上的圆盘移动到 C ,小盘只能在大盘上面。
计算移动次数
当
n
=
1
n =1
n=1 时,A->C 移动一次
当
n
=
2
n=2
n=2 时 ,A->B , A->C , B->C, 移动三次
当
n
=
3
n=3
n=3 时 ,A ->C , A->B , C->B , A->C , B->A , B->C , A->C , 移动七次
设移动
n
n
n 个盘需要移动 g(n) 次,分三个步骤完成:
- 将 n n n 个盘上的 n − 1 n-1 n−1 个盘子借助 C 柱 从 A 柱移动到 B柱,需要 g(n-1) 次
- 将第 n n n 个盘从 A 柱移动到 C 柱 ,需要移动 1 次
- 将 B 柱上的
n
−
1
n-1
n−1 个盘借助 A 柱 移动到 C 柱,需要 g(n-1)次
综上所述,递归关系为:
g ( n ) = 2 g ( n − 1 ) + 1 g(n) = 2g(n-1) + 1 g(n)=2g(n−1)+1
初始条件为: g ( 1 ) = 1 g(1) = 1 g(1)=1
程序源代码
#include<stdio.h>
double g(int n){
double s;
if(n == 1)
s = 1;
else
s = 2*g(n-1)+1;
return s;
}
int main(){
int n;
printf("请输入盘片数n:");
scanf("%d",&n);
if(n<=40)
printf("%d盘的移动次数为:%0.0f\n",n,g(n));
else
printf("%d盘的移动次数为:%.4e\n",n,g(n));
return 0;
}
移动过程
设递归函数 hn(int n,char a,char b,char c)
表示把 n 个盘从 A 柱 借助 B 柱 移动到 C 柱的过程, 函数 mv(char x,char y)
表示 X -> Y
当 n = 1
时,mv(a,c)
当 n > 1
时, 分三步:
- 将
n
n
n 个盘上的
n
−
1
n-1
n−1 个盘子借助 C 柱 从 A 柱移动到 B柱,即
hn(n-1,a,c,b)
- 将第
n
n
n 个盘从 A 柱移动到 C 柱 ,
mv(a,c)
- 将 B 柱上的
n
−
1
n-1
n−1 个盘借助 A 柱 移动到 C 柱,
hn(n-1,b,a,c)
程序源代码
#include<stdio.h>
int k = 0;
void mv(char x,char y){
printf("%c --> %c\t",x,y);
k++;
if(k % 5 == 0)
printf("\n");
}
void hn(int n,char a,char b,char c){
if(n == 1)
mv(a,c);
else{
hn(n-1,a,c,b);
mv(a,c);
hn(n-1,b,a,c);
}
}
int main(){
int n;
printf("请输入盘片数n:");
scanf("%d",&n);
hn(n,'A','B','C');
printf("\n总共移动的次数->%d",k);
return 0;
}