奇数魔方阵、4N魔方阵、2(2N+1)魔方阵
奇数魔方阵
说明:将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。