汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。传说故事可以点这看。
汉诺塔问题是一个经典的数学难题,由 3 根柱子和多个半径不等的圆盘构成,如下图所示:
汉诺塔的操作步骤究竟是什么样的呢,我们可以通过这个游戏来感受一下:点我进入游戏界面!
可见,汉诺塔的大体步骤就如下gif图所示:
图片来自:编程帮——汉诺塔问题
对于汉诺塔问题,易知可以采用分治思想解决,我们可以大致划分为三个步骤解决(设有n个圆盘):
为了能够移动第 n-1 个圆盘从A->B,我们肯定会进行下列操作:
为了能够移动第 n-1 个圆盘从B->C,我们肯定会进行下列操作:
当我们要移动第 n-2 个圆盘时,应先移动他上面的圆盘,即重复上述操作……便可以完成汉诺塔游戏。
这时就可以发现,汉诺塔的拆解过程刚好满足递归算法的定义。
汉诺塔体现了一种重要的思想:分治思想(递归思想)。
#include
void hanoi(int n, char x, char y, char z) //汉诺塔函数
{
if (n==1)
{
printf("%c -> %c\n",x,z); //如果只有 1 个圆盘,则直接从X柱移动到Z柱
}
else //递归调用 hanoi() 函数,将 n-1 个圆盘(除了最大的圆盘)从A柱移动到B柱
{
hanoi(n-1,x,z,y); //将A柱上剩余的最后一个大圆盘移动到Z柱上
printf("%c -> %c\n",x,z);
hanoi(n-1,y,x,z); //递归调用 hanoi() 函数,将B柱上的 n-1 圆盘移动到Z柱上
}
}
int main(void)
{
int n;
while(scanf("%d", &n)!=EOF) //圆盘数量
{
hanoi(n,'A','B','C'); //汉诺塔函数 n个圆盘 3根柱子A、B、C
}
return 0;
}
汉诺塔问题中,n 个圆盘至少需要 2^n-1 次移动操作。
#include
#include
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int flag = pow(2,n); 调用pow函数
printf("%d\n",flag-1);
}
return 0;
}