Pome资料库
Pome 切换暗/亮/自动模式 切换暗/亮/自动模式 切换暗/亮/自动模式 返回首页

双色、三色河内塔

说明

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

而三色河内塔则是将下图左上的圆环经移动成为右上的圆环:

在移动的过程中,一样遵守大盘必须在小盘之下的规则,而颜色顺序则无限制。

解法

无论是双色河内塔或是三色河内塔,其解法观念与之前介绍过的河内塔是类似的,同样也是使用递迴来解,不过这次递迴解法的目的不同,我们先来看只有两个 盘的情况,这很简单,只要将第一柱的黄色移动至第二柱,而接下来第一柱的蓝色移动至第三柱。

再来是四个盘的情况,首先必须用递迴完成下图左上至右下的移动:

接下来最底层的就不用管它们了,因为它们已经就定位,只要再处理第一柱的上面两个盘子就可以了。

那麽六个盘的情况呢?一样!首先必须用递迴完成下图左上至右下的移动:

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

那麽三色河内塔呢?一样,直接来看九个盘的情况,首先必须完成下图的移动结果:

接下来最底两层的就不用管它们了,因为它们已经就定位,只要再处理第一柱上面的三个盘子就可以了。

参考代码

双色河内塔 C

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>

void hanoi(int disks, char source, char temp, char target) {
    if (disks == 1) {
        printf("move disk from %c to %c\n", source, target);
        printf("move disk from %c to %c\n", source, target);
    } else {
        hanoi(disks-1, source, target, temp);
        hanoi(1, source, temp, target);
        hanoi(disks-1, temp, source, target);
    }
}

void hanoi2colors(int disks) {
    char source = 'A';
    char temp = 'B';
    char target = 'C';
    int i;
    for(i = disks / 2; i > 1; i--) {
        hanoi(i-1, source, temp, target);
        printf("move disk from %c to %c\n", source, temp);
        printf("move disk from %c to %c\n", source, temp);
        hanoi(i-1, target, temp, source);
        printf("move disk from %c to %c\n", temp, target);
    }
    printf("move disk from %c to %c\n", source, temp);
    printf("move disk from %c to %c\n", source, target);
}

int main() {
    int n;
    printf("请输入盘数:");
    scanf("%d", &n);

    hanoi2colors(n);

    return 0;
}

三色河内塔 C

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>

void hanoi(int disks, char source, char temp, char target) {
    if (disks == 1) {
        printf("move disk from %c to %c\n", source, target);
        printf("move disk from %c to %c\n", source, target);
        printf("move disk from %c to %c\n", source, target);
    } else {
        hanoi(disks-1, source, target, temp);
        hanoi(1, source, temp, target);
        hanoi(disks-1, temp, source, target);
    }
}

void hanoi3colors(int disks) {
    char source = 'A';
    char temp = 'B';
    char target = 'C';
    int i;

    if(disks == 3) {
        printf("move disk from %c to %c\n", source, temp);
        printf("move disk from %c to %c\n", source, temp);
        printf("move disk from %c to %c\n", source, target);
        printf("move disk from %c to %c\n", temp, target);
        printf("move disk from %c to %c\n", temp, source);
        printf("move disk from %c to %c\n", target, temp);;
    }
    else {
        hanoi(disks/3-1, source, temp, target);
        printf("move disk from %c to %c\n", source, temp);
        printf("move disk from %c to %c\n", source, temp);
        printf("move disk from %c to %c\n", source, temp);

        hanoi(disks/3-1, target, temp, source);
        printf("move disk from %c to %c\n", temp, target);
        printf("move disk from %c to %c\n", temp, target);
        printf("move disk from %c to %c\n", temp, target);

        hanoi(disks/3-1, source, target, temp);
        printf("move disk from %c to %c\n", target, source);
        printf("move disk from %c to %c\n", target, source);

        hanoi(disks/3-1, temp, source, target);
        printf("move disk from %c to %c\n", source, temp);
        
        for (i = disks / 3 - 1; i > 0; i--) {
            if (i>1) {
                hanoi(i-1, target, source, temp);
            }

            printf("move disk from %c to %c\n",
                                 target, source);
            printf("move disk from %c to %c\n",
                                 target, source);

            if (i>1) {
                hanoi(i-1, temp, source, target);
            }
            printf("move disk from %c to %c\n", 
                                   source, temp);
        }
    }
}

int main() {
    int n;
    printf("请输入盘数:");
    scanf("%d", &n);

    hanoi3colors(n);

    return 0;
}

双色河内塔Java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public class Hanoi2Colors { 
    public static void help() {
        System.out.println(
              "Usage: java Hanoi2Colors number_of_disks");
        System.out.println(
              "\t number_of_disks: must be a even number.");
        System.exit(0);
    }
    
    public static void main(String[] args) {
        int disks = 0;        
        try {
            disks = Integer.parseInt(args[0]);
        } catch (Exception e) {
            help();
        }
        if ((disks <= 0) || (disks % 2 != 0)) { 
            help(); 
        }
        hanoi2colors(disks);
    }
     
    public static void hanoi(int disks, 
                      char source, char temp, char target) {
        if (disks == 1) {
            System.out.println("move disk from " 
                               + source + " to " + target);
            System.out.println("move disk from " 
                               + source + " to " + target);
        } else {        
            hanoi(disks-1, source, target, temp);
            hanoi(1, source, temp, target);
            hanoi(disks-1, temp, source, target);
        }
    }
 
    public static void hanoi2colors(int disks) {
        char source = 'A';
        char temp = 'B';
        char target = 'C';
        for (int i = disks / 2; i > 1; i--) {
            hanoi(i-1, source, temp, target);
            System.out.println("move disk from " 
                                   + source + " to " + temp);
            System.out.println("move disk from " 
                                   + source + " to " + temp); 
            hanoi(i-1, target, temp, source);
            System.out.println("move disk from " 
                                   + temp + " to " + target);
        }
        System.out.println("move disk from " 
                                   + source + " to " + temp);
        System.out.println("move disk from " 
                                 + source + " to " + target);
    }
}

三色河内塔Java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
public class Hanoi3Colors {    
    public static void help() {
        System.out.println(
              "Usage: java Hanoi3Colors number_of_disks");
        System.out.println(
      "\tnumber_of_disks: must be a number divisible by 3.");
        System.exit(0);
    }
    
    public static void main(String[] args) {
        int disks = 0;        
        try {
            disks = Integer.parseInt(args[0]);
        } catch (Exception e) {
            help();
        }
        if ((disks <= 0) || (disks % 3 != 0)) { 
            help(); 
        }
        hanoi3colors(disks);
    }
    
    public static void hanoi(int disks, 
                       char source, char temp, char target) {
        if (disks == 1) {
            System.out.println("move disk from " 
                               + source + " to " + target);
            System.out.println("move disk from "
                               + source + " to " + target);
            System.out.println("move disk from "
                               + source + " to " + target);
        } else {        
            hanoi(disks-1, source, target, temp);
            hanoi(1, source, temp, target);
            hanoi(disks-1, temp, source, target);
        }
    }
    
    public static void hanoi3colors(int disks) {
        char source = 'A';
        char temp   = 'B';
        char target = 'C';
        if (disks == 3) {
            System.out.println("move disk from " 
                            + source + " to " + temp);
            System.out.println("move disk from " 
                            + source + " to " + temp);
            System.out.println("move disk from " 
                            + source + " to " + target);
            System.out.println("move disk from " 
                            + temp + " to " + target);
            System.out.println("move disk from " 
                            + temp + " to " + source);
            System.out.println("move disk from " 
                            + target + " to " + temp);
        } else {
            hanoi(disks/3-1, source, temp, target);
            System.out.println("move disk from " 
                            + source + " to " + temp);
            System.out.println("move disk from " 
                            + source + " to " + temp);
            System.out.println("move disk from " 
                            + source + " to " + temp);
            hanoi(disks/3-1, target, temp, source);
            System.out.println("move disk from " 
                            + temp + " to " + target);
            System.out.println("move disk from "
                            + temp + " to " + target);
            System.out.println("move disk from "
                            + temp + " to " + target);
            hanoi(disks/3-1, source, target, temp);
            System.out.println("move disk from " 
                            + target + " to " + source);
            System.out.println("move disk from " 
                            + target + " to " + source);
            hanoi(disks/3-1, temp, source, target);
            System.out.println("move disk from " 
                            + source + " to " + temp);
        
            for (int i = disks / 3 - 1; i > 0; i--) {
                if (i>1) { 
                    hanoi(i-1, target, source, temp); 
                }
                System.out.println("move disk from " 
                         + target + " to " + source);
                System.out.println("move disk from " 
                         + target + " to " + source);
                if (i>1) { 
                    hanoi(i-1, temp, source, target); 
                }
                System.out.println("move disk from " 
                         + source + " to " + temp);
            }
        }
    }
}