1 魔方陣概念
魔方陣是指由1,2,3……n2填充的,每一行、每一列、對角線之和均相等的方陣,階數n = 3,4,5…。魔方陣也稱為幻方陣。
例如三階魔方陣為:
魔方陣有什么的規律呢?
魔方陣分為奇幻方和偶幻方。而偶幻方又分為是4的倍數(如4,8,12……)和不是4的倍數(如6,10,14……)兩種。下面分別進行介紹。
2 奇魔方的算法
2.1 奇魔方的規律與算法
奇魔方(階數n = 2 * m + 1,m =1,2,3……)規律如下:
- 數字1位於方陣中的第一行中間一列;
- 數字a(1 < a ≤ n2)所在行數比a-1行數少1,若a-1的行數為1,則a的行數為n;
- 數字a(1 < a ≤ n2)所在列數比a-1列數大1,若a-1的列數為n,則a的列數為1;
- 如果a-1是n的倍數,則a(1 < a ≤ n2)的行數比a-1行數大1,列數與a-1相同。
2.2 奇魔方算法的C語言實現
1 #include <stdio.h> 2 // Author: http://furzoom.com/ 3 // N為魔方階數 4 #define N 11 5 6 int main() 7 { 8 int a[N][N]; 9 int i; 10 int col,row; 11 12 col = (N-1)/2; 13 row = 0; 14 15 a[row][col] = 1; 16 17 for(i = 2; i <= N*N; i++) 18 { 19 if((i-1)%N == 0 ) 20 { 21 row++; 22 } 23 else 24 { 25 // if row = 0, then row = N-1, or row = row - 1 26 row--; 27 row = (row+N)%N; 28 29 // if col = N, then col = 0, or col = col + 1 30 col ++; 31 col %= N; 32 } 33 a[row][col] = i; 34 } 35 for(row = 0;row<N;row++) 36 { 37 for(col = 0;col < N; col ++) 38 { 39 printf("%6d",a[row][col]); 40 } 41 printf("\n"); 42 } 43 return 0; 44 }
3 偶魔方的算法
偶魔方的情況比較特殊,分為階數n = 4 * m(m =1,2,3……)的情況和階數n = 4 * m + 2(m = 1,2,3……)情況兩種。
3.1 階數n = 4 * m(m =1,2,3……)的魔方(雙偶魔方)
算法1:階數n = 4 * m(m =1,2,3……)的偶魔方的規律如下:
- 按數字從小到大,即1,2,3……n2順序對魔方陣從左到右,從上到下進行填充;
- 將魔方中間n/2列的元素上、下進行翻轉;
- 將魔方中間n/2行的元素左、右進行翻轉。
C語言實現
1 #include <stdio.h> 2 // Author: http://furzoom.com/ 3 // N為魔方階數, 4 #define N 12 5 6 int main() 7 { 8 int a[N][N];//存儲魔方 9 int i, temp;//臨時變量 10 int col, row;//col 列,row 行 11 12 //初始化 13 i = 1; 14 for(row = 0;row < N; row++) 15 { 16 for(col = 0;col < N; col ++) 17 { 18 a[row][col] = i; 19 i++; 20 } 21 } 22 23 //翻轉中間列 24 for(row = 0; row < N/2; row ++) 25 { 26 for(col = N/4;col < N/4*3;col ++) 27 { 28 temp = a[row][col]; 29 a[row][col] = a[N-row-1][col]; 30 a[N-row-1][col] = temp; 31 } 32 } 33 34 //翻轉中間行 35 for(col = 0; col < N/2; col ++) 36 { 37 for(row = N/4;row < N/4 * 3;row ++) 38 { 39 temp = a[row][col]; 40 a[row][col] = a[row][N-col-1]; 41 a[row][N-col-1] = temp; 42 } 43 } 44 45 for(row = 0;row < N; row++) 46 { 47 for(col = 0;col < N; col ++) 48 { 49 printf("%5d",a[row][col]); 50 } 51 printf("\n"); 52 } 53 return 0; 54 }
算法2:階數n = 4 * m(m =1,2,3……)的偶魔方的規律如下:
- 按數字從小到大,即1,2,3……n2順序對魔方陣從左到右,從上到下進行填充;
- 將魔方陣分成若干個4×4子方陣,將子方陣對角線上的元素取出;
- 將取出的元素按從大到小的順序依次填充到n×n方陣的空缺處。
C語言實現
1 #include <stdio.h> 2 // Author: http://furzoom.com/ 3 // N為魔方階數 4 #define N 12 5 6 int main() 7 { 8 int a[N][N];//存儲魔方 9 int temparray[N*N/2];//存儲取出的元素 10 int i;//循環變量 11 int col, row;// col 列,row 行 12 13 //初始化 14 i = 1; 15 for(row = 0;row < N; row++) 16 { 17 for(col = 0;col < N; col ++) 18 { 19 a[row][col] = i; 20 i++; 21 } 22 } 23 //取出子方陣中對角線上的元素,且恰好按從小到大的順序排放 24 i = 0; 25 for(row = 0;row < N; row++) 26 { 27 for(col = 0;col < N; col ++) 28 { 29 if((col % 4 == row % 4) || ( 3 == ( col % 4 + row % 4))) 30 { 31 temparray[i] = a[row][col]; 32 i++; 33 } 34 } 35 } 36 //將取出的元素按照從大到小的順序填充到n×n方陣中 37 i = N*N/2 -1; 38 for(row = 0;row < N; row++) 39 { 40 for(col = 0;col < N; col ++) 41 { 42 if((col % 4 == row % 4) || ( 3 == ( col % 4 + row % 4))) 43 { 44 a[row][col] = temparray[i]; 45 i--; 46 } 47 } 48 } 49 //輸出方陣 50 for(row = 0;row < N; row++) 51 { 52 for(col = 0;col < N; col ++) 53 { 54 printf("%5d",a[row][col]); 55 } 56 printf("\n"); 57 } 58 return 0; 59 }
3.2 階數n = 4 * m + 2(m =1,2,3……)的魔方(單偶魔方)
算法
設k = 2 * m + 1;單偶魔方是魔方中比較復雜的一個。
- 將魔方分成A、B、C、D四個k階方陣,如下圖
這四個方陣都為奇方陣,利用上面講到的方法依次將A、D、B、C填充為奇魔方。
- 交換A、C魔方元素,對魔方的中間行,交換從中間列向右的m列各對應元素;對其他行,交換從左向右m列各對應元素。
- 交換B、D魔方元素,交換從中間列向左m – 1列各對應元素。
C語言實現
#include <stdio.h> // Author: http://furzoom.com/ // N為魔方階數 #define N 10 int main() { int a[N][N] = { {0} };//存儲魔方 int i,k,temp; int col,row;// col 列,row 行 //初始化 k = N / 2; col = (k-1)/2; row = 0; a[row][col] = 1; //生成奇魔方A for(i = 2; i <= k*k; i++) { if((i-1)%k == 0 )//前一個數是3的倍數 { row++; } else { // if row = 0, then row = N-1, or row = row - 1 row--; row = (row+k)%k; // if col = N, then col = 0, or col = col + 1 col ++; col %= k; } a[row][col] = i; } //根據A生成B、C、D魔方 for(row = 0;row < k; row++) { for(col = 0;col < k; col ++) { a[row+k][col+k] = a[row][col] + k*k; a[row][col+k] = a[row][col] + 2*k*k; a[row+k][col] = a[row][col] + 3*k*k; } } // Swap A and C for(row = 0;row < k;row++) { if(row == k / 2)//中間行,交換從中間列向右的m列,N = 2*(2m+1) { for(col = k / 2; col < k - 1; col++) { temp = a[row][col]; a[row][col] = a[row + k][col]; a[row + k][col] = temp; } } else//其他行,交換從左向右m列,N = 2*(2m+1) { for(col = 0;col < k / 2;col++) { temp = a[row][col]; a[row][col] = a[row + k][col]; a[row + k][col] = temp; } } } // Swap B and D for(row = 0; row < k;row++)//交換中間列向左m-1列,N = 2*(2m+1) { for(i = 0;i < (k - 1)/2 - 1;i++) { temp = a[row][k+ k/2 - i]; a[row][k+ k /2 -i] = a[row + k][k+k/2 -i]; a[row + k][k+k/2 -i] = temp; } } //輸出魔方陣 for(row = 0;row < N; row++) { for(col = 0;col < N; col ++) { printf("%5d",a[row][col]); } printf("\n"); } return 0; }
==========================================》
你若要放棄,那我就可以安慰自己了,因為這樣我不再孤獨了,可以參考能夠不斷往前走,成功難道不是早晚的是事嗎?