今天与大家分享一下如何用C语言解决汉诺塔问题。
目录
一.前言
二.找规律⭐
三.总结⭐⭐⭐
四.代码实现⭐⭐
一.前言
有一部很好看的电影《猩球崛起》⭐,说呀,人类为了抗击癌症发明了一种药物🍗,然后给猩猩做了实验,结果猩猩打完药后,变得异常聪明,人们给猩猩测试智力,用的就是汉诺塔,图中猩猩玩的东西就是这个智力玩具啦!⭐
背景:汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
这个游戏的规则是这样的:有A,B,C三个柱子,A柱子上面放着n个盘子,要求把A上面的盘子全都移动到C上,规则是:
- 每次只能移动1个盘子
- 任何时侯不能把一个大的盘子压到小的盘子上面
假设每次移动需要1s的时间,(非常快了,那可是黄金圆盘)那么婆罗门需要多长时间才能把64片黄金圆盘从一根石柱上移动到另一个石柱上呢?
先说结果:64片的圆盘需要移动2^62-1次,算一算,需要移动 18446744073709551615 次,每次一秒,移完这些金片需要5845.42亿年以上,而地球存在至今不过45亿年,太阳系的预期寿命据说也就是数百亿年。真的过了5845.42亿年,不说太阳系和银河系,至少地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭。emm,大梵天绝对是在坑爹呀🍗
二.找规律⭐
当n==1时,只有一个盘子时,直接把盘子从A移到C即可
最少需要:1次
当n==2时,有两个盘子 ,移动如下。
A->B
A->C
B->C
最少需要:3次
当n==3时,移动如下,把三个盘子从A通过B移动到C
把A->C
把A->B
把C->B
把A->C
把B->A
把B->C
把A->C最少需要:7次
当n==4时,问题就稍微有一点点复杂。
1.向n==3那样,我们可以先移动上面3个盘子,从A通过C移到B,只不过n==3时是把三个盘子从A通过B移动到C,不同的是把C和B的地位换了一下。原理是一样的。
2.把A的最后一个盘子移到C
3.再把B上面的三个盘子通过A移到C(还是像n==3的一样)
最少需要:15次
当n==5时呢!
1.和n==4的一样,把上面的4个盘子,从A通过C移到B
2.把A的最后一个盘子从A移到C
3.把B上面的4个盘子从B通过A移到C
最少需要:31次
三.总结⭐⭐
依次类推,我们会发现每次都有三个动作。
1.把n-1个盘子从A通过C移动到B
2.把第n个盘子,从A移动到C
3.再把n-1个盘子从B通过A移动到C
4.不难发现当有n个盘子,移动完成后,最少需要:2^n-1次
四.代码实现⭐
1.从键盘获取盘子的数量🍗
int n; //汉诺塔的盘子个数printf("请输入盘子的个数: ");scanf("%d", &n);
2. 定义汉诺塔函数🍗
void Han(int n, char a, char b, char c)
{if (n == 1)move(a, c); //如果仅有一个盘子,那么直接从A移到Celse{//每次都有三个动作Han(n - 1, a, c, b); //把n-1个盘子,从a通过c移到bmove(a, c); //把第n个盘子从a移到cHan(n - 1, b, a, c); //最后把n-1个盘子从b通过a移到c}
}
3.定义移动函数,用于表示怎么移动🍗
void move(char x, char y)
{printf("把%c->%c\n", x, y);//意思是把x上最上面的盘子移动到y上面count++; //每一动一次计数器加加,最后看一下总共要移动多少次
}
4.定义一个全局变量,用于统计移动的次数🍗
int count;//定义一个全局变量,用于统计移动的次数
5.完整代码🍗
//汉诺塔
int count = 0;//定义一个全局变量count
void move(char x, char y)
{printf("把%c->%c\n", x, y);//意思是把x上最上面的盘子移动到y上面count++; //每一动一次计数器加加,最后看一下总共要移动多少次
}
void Han(int n, char a, char b, char c)
{if (n == 1)move(a, c); //如果仅有一个盘子,那么直接从A移到Celse{Han(n - 1, a, c, b);move(a, c);Han(n - 1, b, a, c);}
}
int main()
{int n; //汉诺塔的盘子个数printf("请输入盘子的个数: ");scanf("%d", &n);Han(n, 'A', 'B', 'C');printf("一共移动的次数=%d", count);return 0;
}
运行结果:
创作不易, 如果这份博客👍对你有帮助,可以给博主一个免费的点赞以示鼓励。
欢迎各位帅哥美女点赞👍评论⭐收藏⭐,谢谢!!!
如果有什么疑问或不同的见解,欢迎在评论区留言哦👀。
祝各位生活愉快⭐