Java 中的魔方

2024年9月10日 | 阅读 6 分钟

幻方是一个由数字组成的方格。一个 m 阶幻方包含从 1 到 m2(包括 1 和 m2)的数字,使得每一行、每一列以及每一条对角线上的数字之和都相等。如果我们将这个和表示为 M,那么 M 完全取决于 m。在数学上,M 的值为:

M = m(m2 + 1) / 2。

因此,

对于 m = 3,

M = 3 x (32+ 1) / 2 = (3 x (9 + 1)) / 2 = (3 x 10) / 2 = 15

对于 m = 5,

M = 5 x (52+ 1) / 2 = (5 x (25 + 1)) / 2 = (5 x 26) / 2 = 130 / 2 = 65

对于 m= 7,

M = 7 x (72+ 1) / 2 = (7 x (49 + 1)) / 2 = (7 x 50) / 2 = 175

对于 m= 9,

M = 9 x (92+ 1) / 2 = (9 x (81 + 1)) / 2 = (9 x 82) / 2 = 369

让我们看几个幻方的例子。

对于 m = 9,我们有一个 9x9 的幻方,其中每一行、每一列以及每一条对角线上的数字之和都为 369。

对于 m = 11,我们有一个 11x11 的幻方,其中每一行、每一列以及每一条对角线上的数字之和都为 671。

填充幻方的规则

让我们讨论一些想法,这将有助于我们编写填充幻方的规则。我们确定无疑的一点是,从 1 到 m2 的每个数字都会出现在幻方中。我们将数字 1 放置在位置 (m / 2, m - 1),然后从那里开始,我们将每一行和每一列视为循环的,因此会进行环绕。

规则 1: 在任何位置,下一个数字的位置都是通过将前一个数字的行号减 1 并将前一个数字的列号加 1 来计算的。在任何时候,如果计算出的行位置变为 -1,那么它将环绕到 m - 1。同样,如果计算出的列位置变为 m,那么它将环绕到 0。

规则 2: 如果在计算出的位置,幻方中已经存在一个数字,那么将计算出的列位置减 2,并将计算出的行位置加 1。

规则 3: 如果计算出的行位置为 -1 且计算出的列位置为 m,那么新位置将是:(0, m - 2)。

让我们举一个例子来更好地理解。

276

951

438

上面的方阵是 3 阶的,包含 9 个元素。

数字 1 的位置是 (3 / 2, 3 - 1) = (1, 2)

数字 2 的位置是 (1 - 1, 2 + 1) = (0, 3) = (0, 0) [3 环绕到 0]

数字 3 的位置是 (0 - 1, 0 + 1) = (-1, 1) = (3 - 1, 1) = (2, 1)

[-1 环绕到 3 - 1 = 2]

数字 4 的位置是 (2 - 1, 1 + 1) = (1, 2)。但是,(1, 2) 的位置已经被数字 1 占用了。因此,应用规则 2,我们得到 (1 + 1, 2 - 2) = (2, 0)。

数字 5 的位置是 (2 - 1, 0 + 1) = (1, 1)

数字 6 的位置是 (1 - 1, 1 + 1) = (0, 2)

数字 7 的位置是 ( 0 - 1, 2 + 1) = (-1, 3) = (0, 3 - 2) = (0, 1)

[这里应用了规则 3]

数字 8 的位置是 ( 0 - 1, 1 + 1) = (-1, 2) = (3 - 1, 2) = (2, 2)

[-1 环绕到 3 - 1 = 2]

数字 9 的位置是 ( 2 - 1, 2 + 1) = (1, 3) = (1, 0)

[3 环绕到 0]

实施

基于以上示例,编写了以下代码。

文件名: MagicSquare.java

输出

The Magic Square for 11: 

Sum of each column or row 671: 

54 42 30 18 6 115 103 91 79 67 66 
41 29 17 5 114 102 90 78 77 65 53 
28 16 4 113 101 89 88 76 64 52 40 
15 3 112 100 99 87 75 63 51 39 27 
2 111 110 98 86 74 62 50 38 26 14 
121 109 97 85 73 61 49 37 25 13 1 
108 96 84 72 60 48 36 24 12 11 120 
95 83 71 59 47 35 23 22 10 119 107 
82 70 58 46 34 33 21 9 118 106 94 
69 57 45 44 32 20 8 117 105 93 81 
56 55 43 31 19 7 116 104 92 80 68

时间复杂度: 上述程序的平均时间复杂度为 O(n2),其中 n 是方阵中的总行数或列数。

空间复杂度: 上述程序的平均空间复杂度为 O(n2),其中 n 是方阵中的总行数或列数。