奇數魔方陣、4N魔方陣、2(2N+1)魔方陣
阿新 • • 發佈:2018-12-11
奇數魔方陣
說明:將1到n(為奇數)的數字排列在nxn的方陣上,且各行、各列與各對角線的和必須相同,如下所示:
解法:填魔術方陣的方法以奇數最為簡單,第一個數字放在第一行第一列的正中央,然後向右(左)上填,如果右(左)上已有數字,則向下填,如下圖所示。一般程式語言的陣列索引多由0開始,為了計算方便,我們利用索引1到n的部份,而在計算是向右(左)上或向下時,我們可以將索引值除以n值,如果得到餘數為1就向下,否則就往右(左)上 ,原理很簡單,看看是不是已經在同一列上繞一圈就對了。
#include<iostream>
#define GET_ARRAY_LEN(arr,row,column) {column = sizeof(arr[0])/sizeof(arr[0][0]);\
row = sizeof(arr)/sizeof(arr[0]);}
#define N 5//這是定義巨集
using namespace std;
void AlgorithmGossip(int (*arr)[N+1] );//二維陣列作為函式引數
int main()
{
int arr[N+1][N+1] = {0};//初始化為0,區域性變數需要此操作。
//int row,column;
//GET_ARRAY_LEN(arr,row,column);
AlgorithmGossip(arr);
for (int i = 1; i <= N ; ++i)
{
for(int j = 1; j <= N; ++j)
cout<< arr[i][j]<<" ";
cout<<endl;
}
return 0;
}
void AlgorithmGossip(int (*arr)[6]){
int indexI = 1, indexJ = (N+1)/2, value = 1;
while(value <= N*N){
arr[indexI][indexJ] = value;
value++;
if(value % N == 1){//先進行簡單規則判斷,再進行陣列陣列下標越界判斷。
indexI++;
}
else{
indexI--;indexJ++ ;
if(indexI < 1)
indexI = N;
if (indexJ > N)
indexJ = 1;
}
}
}
4N魔方陣
說明:與 奇數魔術方陣 相同,在於求各行、各列與各對角線的和相等,而這次方陣的維度是4的倍數。
解法:
簡單的說,就是一個從左上由1依序開始填,但遇對角線不填,另一個由左上由16開始填,但只填在對角線,再將兩個合起來就是解答了;如果N大於2,則以 4X4為單位畫對角:
至於對角線的位置該如何判斷,有兩個公式,有興趣的可以畫圖印證看看,如下所示:
左上至右下:j % 4 == i % 4
右上至左下:(j % 4 + i % 4) == 1
#include<iostream>
#include<iomanip>//操作輸出格式需要加入的標頭檔案
#define N 8
using namespace std;
void AlgorithmGossip(int (*arr)[N+1] );//二維陣列作為函式引數
int main()
{
int arr[N+1][N+1] = {0};//初始化為0,區域性變數需要此操作。
AlgorithmGossip(arr);
for (int i = 1; i <=N; ++i)
{
for(int j = 1; j <=N; ++j)
cout<<setw(3)<<arr[i][j]<<" ";//控制輸出對其一點。
cout<<endl;
}
return 0;
}
void AlgorithmGossip(int (*arr)[N+1]){
int indexI = 1, indexJ = 1, valueIncrease = 1,valueDecrease = N*N;
for(int i = 1; i <= N; ++i)
for (int j = 1; j <= N; ++j)//一趟遍歷,減少程式碼量
{
if(j % 4 == i % 4 || (j % 4 + i % 4)==1)
arr[i][j] = valueDecrease;
else
arr[i][j] = valueIncrease;
valueIncrease++;
valueDecrease--;
}
}
2(2N+1)魔方陣
說明:方陣的維度整體來看是偶數,但是其實是一個奇數乘以一個偶數,例如6X6,其中6=2X3,我們也稱這種方陣與單偶數方陣。
解法:就是一些規則,然後對方陣進行處理,就不列出具體程式碼了,有興趣可以參考別的blog。