河内塔问题

首先关于这个问题网上有两种代码,答案都相同

第一种

#include<iostream>  
 #include<string>  
using namespace std;  
int towers(int size,char f,char t,char s){  //这里f是startTower,t是spareTower,s是endTower
    static int count=0;  
    if  (size==1){  
        cout<<"move from "<<f<<" to "<<s<<endl;  
        count ++;  
        return count;  
    }  
    else{ // n不为1,分为下面一个圆盘和上面n-1个圆盘,先把上面n-1个移动到SpareTower  
        再把最下面一个移动到EndTower,最后把n-1个从SpareTower移动到EndTower  
        用递归就是这么简单!!

        towers(size-1,f,s,t);  
        towers(1,f,t,s);  //***
        towers(size-1,t,f,s);  
    }  
}  
int main(){  
    cout<<"total num is "<<towers(3,'a','b','c')<<endl;  
    return 0;  
}  


要把n个圆盘从一个柱子(StartTower)搬到另一个柱子(EndTower)上,并满足题目的要求,需要借助空闲的柱子(SpareTower)。由于实现n个圆盘的搬移不太容易,可以换个角度思考,把n个圆盘分成1个和(n-1)个圆盘;这(n-1)个圆盘已经排好了顺序,利用3根柱子可以很容易地把这两组圆盘从一个柱子搬移到另一个柱子上。再把(n-1)个圆盘分成1个圆盘和(n-2)个。。。。。。每一个问题都与前一个问题类似,并且规模逐渐缩小,可以考虑采用递归的方法编写。

第二种


move(x, y) {    printf(\t%c-->%c\n",x,y);
}
voidhannuota(intn, chara, charb, charc) //自定义hannuota函数,这里的a,b,c为形参,不代表具体哪根柱子

{
   if(n == 1)
         move(a, c); //调用自定义函数move
                                                                       
   else                                                               
                                                                       
    {        
         hannuota(n-1, a, c, b);  //第一行递归
        
         move(a, c);  //调用自定义函数move//***
        
         hannuota(n-1, b, a, c);  //第二行递归
        
    }
}


intmain(void)

{
   intn;
   
    printf("请输入要移动的块数:\n");
    scanf("%d",& n);
  
    hannuota(n, 'a', 'b', 'c');
   
   return0;
}
/*执行详细步骤:当n = 3 时
                  n = 3           n = 2          n = 1
               
                |               |h(1, a, b, c)=>move(a, c)=> a->c      //1
                |h(2, a, c, b)    |move(a, b)                  a->b      //2
                |               |h(1, c, a, b)=>move(c, b)=> c->b      //3
                |
h(3, a, b, c)    |move(a, c)                                  a->c      //4
                |
                |               |h(1, b, c, a)=>move(b, a)=> b->a      //5                      
                |h(2, b, a, c)    |move(b, c)                  b->c      //6
                |               |h(1, a, b, c)=>move(a, c)=> a->c      //7
                |

执行结果:
请输入要移动的块数:
3
a-->c
a-->b
c-->b
a-->c
b-->a
b-->c
a-->c
*/
这就让我开始思考两代码中间被我打***符号的区别了,为什么他们的效果是一样的,由此开始思考递归的本质,



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值