汉诺问题就是:
给定三根柱子,记为 A,B,C ,其中 A 柱子上有 n 个盘子,从上到下编号为 0 到 n−1 ,且上面的盘子一定比下面的盘子小。问:将 A 柱上的盘子经由 B 柱移动到 C 柱最少需要多少次?
移动时应注意:① 一次只能移动一个盘子
②大的盘子不能压在小盘子上
比如三个盘子的时候,我在网上看到的一个动图
一个盘子移动1次;A->C
两个盘子移动3次:A->B A->C B->C
三个盘子需要移动7次 :A->C A->B C->B A->C B->A B->C A->C
通过规律我们可以得到n个盘子移动的最小次数应该是:2^n-1
当有四个盘子的时候其实就开始复杂起来了,但是我们利用递归,可以把复杂问题简单化。通过图例:
可以把上边的三个盘子看成一个整体,然后将上三个盘子移动B上,再将最后一个盘子移动C上,最后再将三个盘子移动到C上。这样就把A上的盘子全移动到C上了。
也就是说n个盘子
1、将n-1个盘子通过从A经过C移动到B
2、将第n个盘子从A移动到C
3、再将n-1个盘子从B经过A移动到C
原理清楚了我们就开始写代码
void hanoi_step(int n, char a, char b, char c)
{
if (n == 1)
{
printf("%c->%c",A,C);
}
else
{
hanoi_step(n - 1, a, c, b);//将A座上的n-1个盘子借助C座移向B座
printf("%c->%c",A,C);//将A座上最后一个盘子移向C座
hanoi_step(n - 1, b, a, c);//将B座上的n-1个盘子借助A座移向C座
}
}
int main()
{
int n = 0;
scanf("%d", &n);
hanoi_step(n, 'A', 'B', 'C');
return 0;
}
hanoi_step()中 a是起始位置 b是中转位置 c是目的位置
而汉诺塔的最小步数
关系其实就是:
n=1时 f(x)=1
n>1时,f(x)=2*f(x-1)+1
利用递归
int hanio(int n)
{
if (n == 1)
return 1;
else
return 2*hanio(n - 1)+1;
}
int main()
{
int n;
int num;
scanf("%d", &n);
num = hanio(n);
printf("%d", num);
return 0;
}