From Gossip@caterpillar

Algorithm Gossip: 奇數魔方陣

說明

將1到n(為奇數)的數字排列在nxn的方陣上,且各行、各列與各對角線的和必須相同,如下所示:
奇數魔方陣

 解法

填魔術方陣的方法以奇數最為簡單,第一個數字放在第一行第一列的正中央,然後向右(左)上填,如果右(左)上已有數字,則向下填,如下圖所示:
奇數魔方陣
一般程式語言的陣列索引多由0開始,為了計算方便,我們利用索引1到n的部份,而在計算是向右(左)上或向下時,我們可以將索引值除以n值,如果得到餘數為1就向下,否則就往右(左)上,原理很簡單,看看是不是已經在同一列上繞一圈就對了。

實作

#include <stdio.h> 
#include <stdlib.h>

#define N 5

int main(void) {
int i, j, key;
int square[N+1][N+1] = {0};

i = 0;
j = (N+1) / 2;

for(key = 1; key <= N*N; key++) {
if((key % N) == 1)
i++;
else {
i--;
j++;
}

if(i == 0)
i = N;
if(j > N)
j = 1;

square[i][j] = key;
}

for(i = 1; i <= N; i++) {
for(j = 1; j <= N; j++)
printf("%2d ", square[i][j]);
}

return 0;
}

public class Matrix {
public static int[][] magicOdd(int n) {
int[][] square = new int[n+1][n+1];

int i = 0;
int j = (n+1) / 2;

for(int key = 1; key <= n*n; key++) {
if((key % n) == 1)
i++;
else {
i--;
j++;
}

if(i == 0)
i = n;
if(j > n)
j = 1;

square[i][j] = key;
}

int[][] matrix = new int[n][n];

for(int k = 0; k < matrix.length; k++) {
for(int l = 0; l < matrix[0].length; l++) {
matrix[k][l] = square[k+1][l+1];
}
}

return matrix;
}

public static void main(String[] args) {
int[][] magic = Matrix.magicOdd(5);
for(int k = 0; k < magic.length; k++) {
for(int l = 0; l < magic[0].length; l++) {
System.out.print(magic[k][l] + " ");
}
System.out.println();
}
}
}