【蓝桥杯】试题 算法提高 汉诺塔

问题描述

资源限制
  时间限制:1.0s 内存限制:256.0MB
问题描述
  汉诺塔是一个古老的数学问题:
  有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
  每次只能移动一个圆盘;
  大盘不能叠在小盘上面。
  提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须遵循上述两条规则。
  问:如何移?最少要移动多少次?
  
输入格式
  一行,包含2个正整数,一个是N(N<=15),表示要移动的盘子数;一个是M,表示在最少移动d第M步
输出格式
  共2行。
  第一行输出格式为:#No: a->b,表示第M步骤具体移动方法,其中No表示第M步移动的盘子的编号(N个盘子从上到下依次编号为1到n),表示第M步是将No号盘子从a杆移动到b杆(a和b的取值均为{A、B、C})。
  第2行输出一个整数,表示最少移动步数。

样例输入

3 2

样例输出

#2: A->B
7

解题思路

1、本题利用递归思想便可以很简单的理解其思路。在A上有n个盘子时,只需要将上面的n-1个盘中利用C,按规则放置在B上,然后将A上的最后一个盘中放置在C上即可;同理,下一步将B上的n-2个盘子利用C放置在A上即可,以此类推。

void hanoi(int n, char a, char b, char c)
{
     if (n == 1)  
     cout<<a<<"->"<<c<<endl;   
     else
     {
          hanoi(n - 1, a, c, b); //第n-1个要从a通过c移动到b
          cout<<a<<"->"<<c<<endl;
          hanoi(n - 1, b, a, c); //n-1个移动过来之后b变开始盘,b通过a移动到c
      }
}

2、基本过程完成后,根据题意只需要判断每一步移动时,是移动的第几步,以及移动的是哪一个盘子。
a、加入计数count,每次移动计数即可。
b、当A有n个盘子时,首先移动上面n-1个较小的盘子到B,然后移动最下面最大的第n个盘子到C。以此类推,每次移动都是最下面的盘子,因此当只有一个盘子时,一定是第一个盘子。

解题代码

#include <iostream>
using namespace std;
int count=0;
int m;
void hanoi(int n, char a, char b, char c)
{
    if (n == 1)
    {
         count++;
         if(count==m)
            cout<<"#1"<<": "<<a<<"->"<<c<<endl;   
    }
    else
    {
         hanoi(n - 1, a, c, b); //第n-1个要从a通过c移动到b
         count++;
         if(count==m)
            cout<<"#"<<n<<": "<<a<<"->"<<c<<endl;
         hanoi(n - 1, b, a, c); //n-1个移动过来之后b变开始盘,b通过a移动到c
    }
}
int  main()
{
    int n;
    cin>>n>>m;
    hanoi(n, 'A', 'B', 'C');
    cout<<count<<endl;
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值