神奇的魔方陣–(MagicSquare)(1)
本篇文章只對奇數階以及偶數階中階數n = 4K的魔方陣進行討論.下面就讓我們進入正題:
1 :魔方陣的相關資訊:(百度百科)
//baike.baidu.com/item/%E9%AD%94%E6%96%B9%E9%98%B5/10973743?fr=aladdin
2 :奇數階和偶數階魔方陣的排列規律.(源自百度百科) (可跳至第三部分)



#include<assert.h> #include<stdio.h> void Magic_Square_1() { #define ROW 3 #define COL ROW // 等價於 #define COL 3 assert(ROW % 2 != 0); if (ROW % 2 == 0)//ROW & ! == 1 判斷是否為奇數 &(只有全為1,才為1) { return; } int preRow = 0; //記錄上一個數的行坐標 int preCol = 0; //記錄上一個數的列坐標 int ar[ROW][COL] = {}; ar[0][COL / 2] = 1; //先放1 preRow = 0; preCol = COL / 2; for (int i = 2; i <= ROW * COL; i++)//1已經放入所以從2開始進行 { if (ar[(preRow - 1 + ROW) % ROW][(preCol + 1) % COL] == 0) //判斷上一個數的上一行下一列是否有值若沒有則放入當前的i { preRow = (preRow - 1 + ROW) % ROW; preCol = (preCol + 1) % COL; } else { // 若有則i放在上一個數的下一行. preRow = (preRow + 1) % ROW; } ar[preRow][preCol] = i; } for (int i = 0; i < ROW; i++)//列印 { for (int j = 0; j < COL; j++) { printf("%3d", ar[i][j]); } printf("\n"); } #undef ROW //取消定義 #undef COL }
int main()
{
Maagic_Square_1();
return 0;
}
運行結果:
3.2.2) : 將取出來的值按照從大到小的順序(或從小到大的順序)排好,從二維數組的[0][0]下標開始(從二維數組[ROW – 1][COL – 1]的位置開始) 依次填入到數組中空白的位置.
(重點)排列n= 4*k 階的魔方陣的關鍵是取出各個四階魔方陣的對角線的元素.我們可以發現:所有在對角線的元素的行列下標只差都滿足一定的規律:
即 |row – col|(絕對值) % 4 == 0 (對應圖中黃色部分)或者(row + col)%4 == 3(對應圖中紅色部分) .同時我們可以定義一個數組br[ROW*ROW/2],
在第一步填入數據時對其行列下標進行判斷,若滿足對角線元素下標的特點,直接將數值存放到br中,同時對二維數組相應的位置賦零值.
這樣br 中的數就是從小到大排列的,只需要在第二步時從二維數組ar 的ar[ROW – 1][COL – 1]的位置開始,
依次將數組br中的值填入到數組中空白的位置.
程式碼如下:
#include<stdio.h> #include<assert.h> void Magic_Square_4K() { #define ROW 8 #define COL ROW int ar[ROW][COL] = {}; int br[ROW*ROW/2] = {};//用來存儲4階方陣對角線元素. int num = 1;//從1開始填入 int k = 0;//數組br下標. for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { if((i-j)%4==3||(i-j)%4==0|| (j - i) % 4 == 3 || (j - i) % 4 == 0) {//先控制對角線元素為零,並將應該填在對角線的這些數記錄到br中. br[k] = num; k += 1; ar[i][j] = 0; } else { ar[i][j] = num; } num++; } } int tag = 0; for (int i = ROW - 1; i >= 0; i--)//將br中的數按照順序,從ar[ROW-1][COl-1]開始對ar中為零的元素賦值. { for (int j = COL - 1; j >= 0; j--) { if (ar[i][j] == 0) { ar[i][j] = br[tag]; tag += 1; } } } for (int i = 0; i < ROW; i++)//列印 { for (int j = 0; j < COL; j++) { printf("%4d", ar[i][j]); } printf("\n"); } #undef ROW #undef COL } int main() { Magic_Square_4K(); return 0; }
運行結果:
未完待續…