汉诺塔
2015-09-22 23:13
225 查看
问题描述:
有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
每次只能移动一个圆盘;
大盘不能叠在小盘上面。
提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须尊循上述两条规则。
问:如何移?最少要移动多少次?
问题分析:
设汉诺塔盘子从上到下,依次为 d1, d2,d3,......dn, ( n>0)
记 上面前k个盘子整体为 S(k) (k>1)
递归的思路是,先假设前n-1个盘子为一个整体S(n-1),要把盘子从A移动C, 只需要借助桥梁B即可完成,具体移动方法是:
(1)S(n-1):A=>B
(2) dn:A=>C
(3) S(n-1):B=>C
实际上就是一个包含四个参数 f(n ,A, B, C) 的函数
第一步和第三步实际上就回到n-1层汉诺塔问题,
拿第一步来说,把前n-2个盘子看为一个整体S(n-2), 问题变为把盘子从A移动B,这时需要把C作为桥梁,移动方法是:
(4)S(n-2): A=>C
(5) d(n-1): A=>B
(6) S(n-2): C=>B
实际上和(1),(2),(3)的步骤没有区别,只是【桥梁】 B和C对调了一下而已:
通过(1),(2),(3)总结函数式:
(1) f(n-1, A, C, B) // 参数A为原地点,C为桥梁, B为目的地
(2) n : A=>C // 把最底下的盘子从 原地点=》目的地
(3) f(n-1, B, A, C) // 参数 B为原地点,A为桥梁,C为目的地
C#编程:
将n个盘从from柱移到to柱,以aux柱为辅助柱,仅有一个盘时,直接从from柱移到to柱,
有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
每次只能移动一个圆盘;
大盘不能叠在小盘上面。
提示:可将圆盘临时置于B杆,也可将从A杆移出的圆盘重新移回A杆,但都必须尊循上述两条规则。
问:如何移?最少要移动多少次?
问题分析:
设汉诺塔盘子从上到下,依次为 d1, d2,d3,......dn, ( n>0)
记 上面前k个盘子整体为 S(k) (k>1)
递归的思路是,先假设前n-1个盘子为一个整体S(n-1),要把盘子从A移动C, 只需要借助桥梁B即可完成,具体移动方法是:
(1)S(n-1):A=>B
(2) dn:A=>C
(3) S(n-1):B=>C
实际上就是一个包含四个参数 f(n ,A, B, C) 的函数
第一步和第三步实际上就回到n-1层汉诺塔问题,
拿第一步来说,把前n-2个盘子看为一个整体S(n-2), 问题变为把盘子从A移动B,这时需要把C作为桥梁,移动方法是:
(4)S(n-2): A=>C
(5) d(n-1): A=>B
(6) S(n-2): C=>B
实际上和(1),(2),(3)的步骤没有区别,只是【桥梁】 B和C对调了一下而已:
通过(1),(2),(3)总结函数式:
(1) f(n-1, A, C, B) // 参数A为原地点,C为桥梁, B为目的地
(2) n : A=>C // 把最底下的盘子从 原地点=》目的地
(3) f(n-1, B, A, C) // 参数 B为原地点,A为桥梁,C为目的地
C#编程:
将n个盘从from柱移到to柱,以aux柱为辅助柱,仅有一个盘时,直接从from柱移到to柱,
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 汉诺塔 { class Program { static int count = 0; static void Main(string[] args) { Console.Write("请输入圆盘个数:"); int N = 0; N = Convert.ToInt32(Console.ReadLine()); // 将N个圆盘从A柱移到C柱,移动时利用B柱为辅助柱 hannouta('A', 'C', 'B', N); Console.WriteLine("总共需要移动次数:" + count); Console.ReadKey(); } static void hannouta(char from, char to, char aux, int n) { // 仅有一个盘时,直接从from柱移到to柱 if (n == 1) { Console.WriteLine("1: " + from + "->" + to); count++; } else { // 将n - 1个盘从from柱移到aux柱,以to柱为辅助柱 hannouta(from, aux, to, n - 1); //n 代表第n盘子 // 将最下的圆盘从from柱移到to柱 Console.WriteLine(n + ": " + from + "->" + to); count++; // 将n - 1个盘从aux柱移到to柱,以from柱为辅助柱 hannouta(aux, to, from, n - 1); } } } }