• 双色汉诺塔【分离型】


    来源:http://blog.csdn.net/heaven13483/article/details/8330503

    说明

    双色河内塔是由之前所介绍过的河内塔规则衍生而来,双色河内塔的目的是将下图左上的圆环位置经移动成为右下的圆环位置:

     

    解法

    双色河内塔或是原始的河内塔,其解法观念与之前介绍过的河内塔是类似的,同样也是使用递回来解,不过这次递回解法的目的不同,我们来看双色的情况,这很简单,
    只要将第一柱的黄色移动至第二柱,而接下来第一柱的蓝色移动至第三柱。再来是四个盘的情况,首先必须用递回完成下图左上至右下的移动:

     

    接下来最底层的就不用管它们了,因为它们已经就定位,只要再处理第一柱的上面两个盘子就可以了。那么六个盘的情况呢?一样!首先必须用递回完成下图左上至右下的移动:

     

    接下来最底层的就不用管它们了,因为它们已经就定位,只要再处理第一柱上面的四个盘子就可以了,这又与之前只有四盘的情况相同,接下来您就知道该如何进行解题了,无论是八个盘、十个盘以上等,都是用这个观念来解题。

    简单的写一下程序:

    【代码2做了一点点小改动,加了一点注释、同时输出具体的移动过程。】

    代码1:

     1 //来源:http://blog.csdn.net/heaven13483/article/details/8330503
     2 #include <iostream>
     3 using namespace std;
     4 
     5 int step=0;
     6 
     7 //将在B中最底下的两个盘子当中上边的那一个移动到C
     8 void Move1(char B,char C)
     9 {
    10     cout<<"将一个从"<<B<<"移动到"<<C<<endl;
    11 }
    12 
    13 //移动n对盘子:将n对盘子从A整体移动到C
    14 void Move2(int n,char A,char B,char C)
    15 {
    16     if (n<1)
    17     {
    18         return ;
    19     }
    20     
    21     if (1 == n)
    22     {
    23         cout<<"将两个从"<<A<<"一个一个移动到"<<C<<endl;
    24     }
    25     else
    26     {
    27         Move2(n-1,A,C,B);
    28         Move2(1,A,B,C);
    29         Move2(n-1,B,A,C);
    30     }
    31 }
    32 
    33 //分离n对盘子:分离两种颜色的盘子分别放在B和C上面
    34 void Move3(int n)
    35 {
    36     if (n == 1)
    37     {
    38         //Move2(1,'A','C','B');
    39         Move1('A','B');
    40         Move1('A','C');
    41         return;
    42     }
    43     
    44     Move2(n-1,'A','B','C');
    45     Move2(1,'A','C','B');
    46     Move2(n-1,'C','B','A');
    47     Move1('B','C');
    48     Move3(n-1);
    49     
    50 }
    51 
    52 int main()
    53 {
    54     int n;
    55     scanf("%d",&n);//表示有n对盘子。每一对两个盘子,大小相同,颜色不同。 
    56     freopen("out.txt","w",stdout);
    57     Move3(n);//移动n对盘子:分离两种颜色的盘子分别放在B和C上面 
    58     return 0;
    59 }

    代码2:

     1 //来源:http://blog.csdn.net/heaven13483/article/details/8330503
     2 #include <iostream>
     3 using namespace std;
     4 
     5 int step=0;
     6 
     7 //将在B中最底下的两个盘子当中上边的那一个移动到C
     8 void Move1(char B,char C)
     9 {
    10     step++;
    11     cout<<"step:"<<step<<"   "<<B<<"---->"<<C<<endl;
    12 }
    13 
    14 //移动n对盘子:将n对盘子从A整体移动到C
    15 void Move2(int n,char A,char B,char C)
    16 {
    17     if (n<1)
    18     {
    19         return ;
    20     }
    21     
    22     if (1 == n)
    23     {
    24         //cout<<"将两个从"<<A<<"一个一个移动到"<<C<<endl;
    25         Move1(A,C);
    26         Move1(A,C);
    27     }
    28     else
    29     {
    30         Move2(n-1,A,C,B);//把n-1对盘子从A移动到B 
    31         Move2(1,A,B,C);//把1对盘子从A移动到C 
    32         Move2(n-1,B,A,C);///把n-1对盘子从B移动到C 
    33     }
    34 }
    35 
    36 //分离n对盘子:分离两种颜色的盘子分别放在B和C上面
    37 void Move3(int n)
    38 {
    39     if (n == 1)
    40     {
    41         //Move2(1,'A','C','B');
    42         Move1('A','B');
    43         Move1('A','C');
    44         return;
    45     }
    46     
    47     Move2(n-1,'A','B','C');//把A顶上的n-1对盘子从A移动到C 
    48     Move2(1,'A','C','B');//把A最底下的1对盘子移动到B 
    49     Move2(n-1,'C','B','A');//把C上的n-1对盘子从C移动到A
    50     Move1('B','C');
    51     Move3(n-1);//分离n-1对盘子 
    52     
    53 }
    54 
    55 int main()
    56 {
    57     int n;
    58     scanf("%d",&n);//表示有n对盘子。每一对两个盘子,大小相同,颜色不同。 
    59     freopen("out.txt","w",stdout);
    60     Move3(n);//移动n对盘子:分离两种颜色的盘子分别放在B和C上面 
    61     return 0;
    62 }
  • 相关阅读:
    串口操作
    图片转化成二进制数据、等比缩放
    DSO Framer Control Object 操作word文件
    C#图片存入数据库及其读出显示
    对话框的用法
    C#读取数据库中的表
    将Resource中的图片资源动态绑定到PictureBox中:
    ProgressBar
    C# 操作数据库表和数据库
    操作系统–进程管理
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/5192239.html
走看看 - 开发者的网上家园