一、魔方介紹
魔方(這里是簡稱,也可以叫幻方、魔術矩陣,Magic Square)是 n×n 正方形網格(n 為每側的單元數),里面每個單元格填充了不同的正整數 1, 2, 3, ... , n2,並且每一行、每一列和對角線中的正整數之和相等。每行、每列以及對角線上的單元格里的正整數之和又叫做魔術常數或魔方的魔術和。

幻方歷史:
《系辭》雲:“河出圖,洛出書,聖人則之。”在宋朝之前,洛書的記述只有文字。
九宮圖實物最早發現於西漢,1977年中國考古學家在安徽阜陽縣雙古堆西漢古墓中發現漢文帝七年(前173年)的太乙九宮占盤,乃是中國漢代幻方的實物。東漢《數術記遺》也有記載。
后來陳摶以降認為河圖洛書的洛書代表九宮圖,為 1...9 這 9 個數,而 3 行、3 列以及兩對角線上各自的數之和均為 15。
二、奇數階幻方構造法
幻方可以使用 N 階方陣來表示,方陣的每行、每列以及兩條對角線的和都等於常數 M2(N),如果填充數為 1, 2, ... , N2,那么有

三個成立條件:
- 下一個數字的位置是通過將前一個數字的行號減 1,再將前一個數字的列號加 1來計算的。在任何時候,如果計算出的行位置變為 -1,它將繞到 n - 1。同樣,如果計算出的列位置變為 n,則它將繞到 0。
- 如果幻方在計算位置處已經包含數字,則計算列位置將減少 2,計算行位置將增加 1。
- 如果計算出的行位置為 -1 且計算出的列位置為 n,則新位置將為:(0, n-2)。
其時間復雜度為 O(n2)。
三、奇數階幻方構造代碼
1 package algorithm; 2 3 /** 4 * 奇數階魔方矩陣 5 */ 6 public class MagicSquare { 7 /** 8 * 生成奇數階魔方矩陣(n*n), 魔方里面填充范圍內不同的正整數:1, 2, 3, ... , n^2 9 * 10 * @param n 奇數階 11 */ 12 private static void generateSquare(int n) { 13 int[][] magicSquare = new int[n][n]; 14 15 /** 16 * 初始化正整數1的位置 17 */ 18 int i = n / 2; // row 19 int j = n - 1; // column 20 21 /* 把一個個樹填充進魔方中 */ 22 for (int num = 1; num <= n * n;) { 23 if (i == -1 && j == n) { // 條件3 24 j = n - 2; 25 i = 0; 26 } else { 27 if (j == n) // 條件1 28 j = 0; 29 if (i < 0) 30 i = n - 1; 31 } 32 33 if (magicSquare[i][j] != 0) { // 條件2 34 j -= 2; 35 i++; 36 continue; 37 } else { 38 magicSquare[i][j] = num++; // 把一個個正整數填進對應位置 39 } 40 j++; 41 i--; 42 } 43 44 System.out.println("The Magic Square for " + n + ":"); // 打印魔方的階數 45 System.out.println("Sum of each row or column " + (n * (n * n + 1) / 2) + ":"); // 打印此魔方的魔術常數,即每行、每列、對角線之和 46 47 /* 打印魔方方陣 */ 48 for (i = 0; i < n; i++) { 49 for (j = 0; j < n; j++) { 50 System.out.print(magicSquare[i][j] + " "); 51 } 52 System.out.println(); 53 } 54 } 55 56 public static void main(String[] args) { 57 /* n為奇數時有效 */ 58 int n = 5; 59 generateSquare(n); 60 } 61 }
