渣渣渣变渣渣系列(5)

一、题目描述:

现在有n个圆盘从上往下从小到大叠在第一根柱子上,要把这些圆盘全部移动到第三根柱子要怎么移动呢?请找出需要步骤数最少的方案因此我们可以将问题简化描述为:n个盘子和3根柱子:A(源)、B(目的)、C(备用),盘子的大小不同且中间有一孔,可以将盘子“串”在柱子上,每个盘子只能放在比它大的盘子上面。起初,所有盘子在A柱上,问题是将盘子一个一个地从A柱子移动到B柱子。移动过程中,可以使用C柱,但盘子也只能放在比它大的盘子上面。

二、算法思想:

汉诺塔问题是递归算法的典型代表,递归的本质是大而化小,利用的是计算机的堆栈来实现的。递归过程可以分为以下几步:

第一步:将n-1个盘子从A柱移动至B柱(借助C柱为过渡柱)
第二步:将A柱底下最大的盘子移动至B柱
第三步:将C柱的n-1个盘子移至B柱(借助A柱为过渡柱)

其中将n-1作为一个整体,假想进行操作,这里就利用的递归的思想,我们可以比作生活中的领导安排任务,领导将任务一层一层往下传递,领导都是不做具体的事,把落实放到最底层去,最底层然后一级一级往上汇报,最终完成领导的任务。

三、核心代码:

 

 void Hanoi(int n,char a,char b,char c)
{

   if(n==1)
       Move(n,a,b);//递归的出口
   else
   {
       Hanoi(n-1,a,c,b);//将n-1个盘由实参a移动到实参c(由函数形参可以看出,每次移动的是a和b,也就是Hanoi(n,a,b,c)中的前两个a和b。)
       Move(n,a,b);//将最大盘由a移动到b(函数实际起操作的部分,将形参a移动到b)
       Hanoi(n-1,c,b,a);//将n-1个盘由实参c移动到实参b(由函数形参可以看出,每次移动的是a和b,也就是Hanoi(n,a,b,c)中的前两个a和b。)
   }
}
 void Move(int n,char a,char b)
 {
     printf("Move %d: from %c to %c\n",n,a,b);
 }

 

 

 

 

 

 

 

 

四、完整代码:

 

/*
汉诺塔问题
*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define EPS 1e-6
 void Hanoi(int n,char a,char b,char c);
 void Move(int n,char a,char b);
 main()
 {
     int n=0;
     printf("please input the scale of Hanoi\n");
     scanf("%d",&n);
     Hanoi(n,'A','B','C');
 }
 void Hanoi(int n,char a,char b,char c)
{

   if(n==1)//递归的出口
       Move(n,a,b);
   else
   {
       Hanoi(n-1,a,c,b);//将n-1个盘由实参a移动到实参c(由函数形参可以看出,每次移动的是a和b,也就是Hanoi(n,a,b,c)中的前两个a和b。)
       Move(n,a,b);//将最大盘由a移动到b(函数实际起操作的部分,将形参a移动到b)
       Hanoi(n-1,c,b,a);//将n-1个盘由实参c移动到实参b(由函数形参可以看出,每次移动的是a和b,也就是Hanoi(n,a,b,c)中的前两个a和b。)
   }
}
 void Move(int n,char a,char b)
 {
     printf("Move %d: from %c to %c\n",n,a,b);
 }

 

 

 

 

 

五、测试分析:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值