√ C# - 03.怎么利用递归解决汉诺塔问题

1. 题目

如下图所示,有三根相邻的柱子,分别标记为A、B、C。柱子A从上到下按金字塔状叠放着n个大小依次递增的盘子,若此时需要把所有的盘子移动到柱子C上,条件是每次只能移动一个盘子,而且所有柱子上都不能出现大盘子落在小盘子上方的情况,请问至少需要移动多少次?

在这里插入图片描述

2. 解法

(1)考虑只有一个盘子的情况,此时只需要把柱子A上的盘子移动到柱子C即可,记为“A -> C”。
(2)考虑有两个盘子的情况,此时需要先把柱子A上的小盘子移动到柱子B,记为“A -> B”,再把柱子A上的大盘子移动到柱子C,记为“A -> C”,最后把柱子B上的小盘子移动到柱子C即可,记为“B -> C”。
(3)考虑有两个以上即n个盘子的情况,从中间移动柱子A最下面的盘子这一步开始看,此时柱子A上只有一个最大的盘子,柱子B上依次叠放着n-1个盘子,柱子C上没有盘子。这一步之前的步骤可以看作是把n-1个盘子从柱子A上经柱子C辅助移动到柱子B上的过程,然后这一步直接把柱子A上最大的盘子移动到柱子C即可,这一步之后的步骤可以看作是把n-1个盘子从柱子B上经柱子A辅助移动到柱子C上的过程。

在这里插入图片描述

(4)对比步骤(2)和(3),可以看出这是一个递归移动的过程,现在利用一个移动方法来显示盘子移动的轨迹,方法的参数分别是盘子的个数、柱子A、柱子B、柱子C。

3. 代码

using System;

namespace _03
{
    class Program
    {
        public static int count;

        static void Main(string[] args)
        {
            while (true)
            {
                count = 0;
                Console.WriteLine("请输入盘子的个数:");
                Hanoi(int.Parse(Console.ReadLine()), "A", "B", "C");
                Console.WriteLine($"至少需要移动{count}次!");
                Console.WriteLine("是否继续(y/n)?");
                if (Console.ReadLine().Contains("n"))
                {
                    break;
                }
            }
        }

        public static void Hanoi(int n, string A, string B, string C)
        {
            if (n == 1)
            {
                Console.WriteLine($"{A} -> {C}");
                count++;
                return;
            }
            Hanoi(n - 1, A, C, B);//A -> B
            Hanoi(1, A, B, C);//A -> C
            Hanoi(n - 1, B, A, C);//B -> C
        }
    }
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值