魔方阵 :n=4k(n=4,8,12,16... k=1,2,3,4..)
一、规律
(1)把1到n^2这些数字按照顺序填写到n*n格子中,按 4*4把它分割成k*k个小方阵。
(因为n是4的倍数,所以一定能用4*4个小方阵分割)
(2) 将各个对角线上的数字,换成与它互补的数字。
(互补:最大数字与最小数字的和,即n*n+1)
二、填数过程(以8*8方阵为例)
① 把1到8^2=64这些数字按照顺序填写到8*8格子中,按 4*4把它分割成2*2个小方阵。
② 将各个对角线上的数字,换成与它互补的数字。
(1-----64)
(10----55)
(19---46)
(28---37)
三、程序部分说明
a、在小正方形的4*4中寻找右下方向对角线第一个元素,观察规律,发现 行%4==0,并且 (行-列)%4==0
对角线元素取其互补数 行+1 列+1 往右下方向遍历
b、在小正方形的4*4中寻找右上方向对角线第一个元素,观察规律,发现 行%4==3,并且 (行+列 %4==3
对角线元素取其互补数 行-1 列+1 往右上方向遍历
四、程序编写如下:
#include<stdio.h>
#include<math.h>
#include<assert.h>
void Even4kMagicSquare(int n)
{
assert(n % 4 == 0);//保证是4的倍数
int a[100][100];
int num = 1;
for (int i = 0; i < n; i++)//从1到n的平方依次赋值
{
for (int j = 0; j < n; j++)
{
a[i][j] = num;
num++;
}
}
for (int i = 0; i < n; i++)//小正方形的对角线上的数字取其补数
{
for (int j = 0; j < n; j++)
{
if (i % 4 == 0 && abs(i - j) % 4 == 0)//右下对角线(0,0)(0,4)(4,0)(4,4)...
{
for (int k = 0; k < 4; k++)//abs为整型绝对值函数
{
a[i + k][j + k] = abs(n*n + 1 - a[i + k][j + k]);
}
}
if (i % 4 == 3 && (i + j) % 4 == 3)//右上方向对角线(3,0)(3,4)(7,0)(7,4)...
{
for (int k = 0; k < 4; k++)
{
a[i - k][j + k] = abs(n*n + 1 - a[i - k][j + k]);
}
}
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%-5d", a[i][j]);
}
printf("\n\n");
}
}
int main()
{
Even4kMagicSquare(8);
return 0;
}
运行结果: