一、汉诺塔问题介绍
有A、B、C三根杆,其中A杆由下至上、由大到小按顺序放置64个盘子。现将A杆上的盘子全部移到C杆上,并仍保持原有顺序。每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下、小盘在上,移动过程中盘子可以置于A、B、C任一杆上。
二、问题分析
1、当A杆只有一个盘子时,直接移动即可。
2、当A杆有两个盘子时,运动轨迹如下:第一个盘子A->B;第二个盘子A->C;第一个盘子B->C。
3、当A杆有三个盘子时,移动轨迹如下:第一个盘子A->C;第二个盘子A->B;第一个盘子C->B;第三个盘子A->C;第一个盘子B->A;第二个盘子B->C;第一个盘子A->C。
4、当A杆有四个盘子时,移动轨迹如下:第一个盘子A->B;第二个盘子A->C;第一个盘子B->C;第三个盘子A->B;第一个盘子C->A;第二个盘子C->B;第一个盘子A->B;第四个盘子A->C;第一个盘子B->C;第二个盘子B->A;第一个盘子C->A;第三个盘子B->C;第一个盘子A->B;第二个盘子A->C;第一个盘子B->C。
综上所述,可以分为三步:
a.将前n-1个盘子移动到B杆上
b.第n个盘子移动到C杆上
c.将前n-1个盘子移动到C杆上
三、编程解决
通过分析,我们可以使用递归解决汉诺塔问题。代码如下:
#include <stdio.h>
int count = 0; //记录移动次数
void Move(int n,char x, char y) //将第n个盘子从x杆移动到y杆
{
printf("第%d个盘子%c -> %c\n", n, x, y);
}
void Hanoi(int n, char A, char B, char C) //n个盘子,从A杆移到C杆,B作为中介
{
if (n > 1)
{
Hanoi(n - 1, A, C, B); //前n-1个盘子从A杆移到B杆,C作为中介
Move(n, A, C); //第n个盘子从A杆移到C杆
count++;
Hanoi(n - 1, B, A, C); //前n-1个盘子从B杆移到C杆,A作为中介
}
else
{
Move(n, A, C);
count++;
return count;
}
}
int main()
{
int n = 0;
char a = 'A';
char b = 'B';
char c = 'C';
printf("请设定A杆上盘数:");
scanf("%d", &n);
printf("移动轨迹如下:\n");
Hanoi(n, a, b, c);
printf("一共移动了%d次\n", count);
return 0;
}
运行结果: