三维魔方是一种将整数按照n x n x n的模式排列,使得每一行、每一列、每一个柱子以及四个主要空间对角线上的数字之和都相等的数学结构。这个和被称为魔方的魔常数。本文将探讨构建三维魔方的不同算法,包括奇数阶和偶数阶魔方的构建方法。
阶数(Order):n x n x n魔方中的n值。
魔常数(Magic constant):任何一行、一列、一个柱子或对角线上数字的和。其值等于n(n^3 + 1) / 2。
暹罗方法是一种构建奇数阶魔方的方法。这种方法可以扩展到三维空间,以构建三维魔方。假设读者已经理解暹罗方法。
可以使用索引表示法来表示任何魔方,例如[1,2,3]代表第一层、第二行和第三列。索引从[0,0,0]开始,最大值是[n-1,n-1,n-1]。任何移动都会像吃豆人或矩阵中的火车隧道一样环绕。-1的值等同于n-1,n等同于0。
从一个空的魔方开始。步骤如下:
构建魔方的逻辑可以从以下魔方扩展:
1 15 14 4
12 6 7 9
8 10 11 5
13 3 2 16
上面的魔方可以通过以下方式创建:
计算魔方索引[r,c]的奇偶性逻辑:
int nBy4 = n / 4;
boolean parity = false;
if (r >= nBy4 && r < 3 * nBy4) {
parity = true;
}
if (c >= nBy4 && c < 3 * nBy4) {
parity = !parity;
}
类似地,可以构建魔方。
这里的逻辑变得更加复杂,因此本文不包括在内。可以使用Medjig方法构建这些魔方。在演示源代码中,还包含了生成任何阶数(包括单偶数阶魔方)的魔方的代码。相同的逻辑可以扩展到生成魔方。
以下是Java语言的代码实现:
public static int[][][] getMagicCube(int n) {
if (n % 2 == 1) {
int[][][] magicCube = new int[n][n][n];
// layer index, row index, column index
int l, r, c;
l = 0;
r = n / 2;
c = n / 2;
// 初始化魔方
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < magicCube.length; k++) {
magicCube[i][j][k] = 0;
}
}
}
int last = (int) Math.pow(n, 3);
for (int i = 0; i < last; i++) {
magicCube[l][r][c] = i + 1;
l--;
l = normalize(n, l);
c--;
c = normalize(n, c);
if (magicCube[l][r][c] != 0) {
r--;
r = normalize(n, r);
c++;
c = normalize(n, c);
if (magicCube[l][r][c] != 0) {
r++;
r = normalize(n, r);
l += 2;
l = normalize(n, l);
}
}
}
return magicCube;
} else if (n % 4 == 0) {
int[][][] magicCube = new int[n][n][n];
int lastPlusOne = (int) Math.pow(n, 3) + 1;
int number = 1;
int nBy4 = n / 4;
for (int l = 0; l < n; l++) {
for (int r = 0; r < n; r++) {
for (int c = 0; c < magicCube.length; c++) {
boolean parity = false;
if (l >= nBy4 && l < 3 * nBy4) {
parity = true;
}
if (r >= nBy4 && r < 3 * nBy4) {
parity = !parity;
}
if (c >= nBy4 && c < 3 * nBy4) {
parity = !parity;
}
magicCube[l][r][c] = (parity) ? lastPlusOne - number : number;
number++;
}
}
}
return magicCube;
}
throw new RuntimeException("Singly even magic cubes are not returned by this method.");
}
// index should be between 0 to n-1
private static int normalize(int n, int index) {
while (index < 0) {
index = index + n;
}
while (index > n - 1) {
index = index - n;
}
return index;
}
这个概念可以扩展到更高维度的立方体(超立方体)。可以访问网站,在那里可以生成任何给定阶数和维度的魔方。
以下是通过代码生成的5阶魔方示例:
第1层:
109 77 75 43 11
97 70 38 6 104
65 33 1 124 92
28 21 119 87 60
16 114 82 55 48
第2层:
15 108 76 74 42
103 96 69 37 10
91 64 32 5 123
59 27 25 118 86
47 20 113 81 54
第3层:
41 14 107 80 73
9 102 100 68 36
122 95 63 31 4
90 58 26 24 117
53 46 19 112 85
72 45 13 106 79
40 8 101 99 67
3 121 94 62 35
116 89 57 30 23
84 52 50 18 111
78 71 44 12 110
66 39 7 105 98
34 2 125 93 61
22 120 88 56 29
115 83 51 49 17