奇数:阶数n=m(m =1,3,5……)的奇魔方规律如下:
- 将1放在第一行中间一列。
- 从2开始直到n×n止各数依次按下列规则存放:每一个数存放的行比前一个数的行数减1,列数加1。
- 如果上一个数的行数为1,则下一个数的行数为n,列数加1。如果上一个数的列数为n时,下一个数的列数为1,行数减1。
- 如果按上面的规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。
void MagicSquare() { #define ROW 3 #define COL ROW int arr[ROW][COL] = {0}; assert(ROW%2 != 0);//(ROW&1)!=0 arr[0][COL/2] = 1; int currow = 0; int curcol = COL/2; for(int i=2;i<=ROW*COL;i++) { currow = (currow-1+ROW)%ROW; curcol = (curcol+1)%COL; if(arr[currow][curcol] != 0) { currow = (currow+2)%ROW; curcol = (curcol-1+COL)%COL; } arr[currow][curcol] = i; } for(int i=0;i<ROW;i++) { for(int j=0;j<COL;j++) { printf("%-2d ",arr[i][j]); } printf("\n"); } }
运行结果为:
偶魔方的算法:偶魔方的情况比较特殊,分为阶数n = 4 * m(m =1,2,3……)的情况和阶数n = 4 * m + 2(m = 1,2,3……)情况两种。
双偶:阶数n = 4 * m(m =1,2,3……)的偶魔方的规律如下:
- 按数字从小到大,即1,2,3……n2顺序对魔方阵从左到右,从上到下进行填充;
- 将魔方中间n/2列的元素上、下进行翻转;
- 将魔方中间n/2行的元素左、右进行翻转。
# include<stdio.h>
#define N 4
void MagicSquare()
{
#define ROW N
#define COL ROW
int a = 1;
int temp;
int arr[ROW][COL] = {0};
int currow;
int curcol;
for(currow=0;currow<N;currow++)//魔方阵填充
{
for(curcol=0;curcol<N;curcol++)
{
arr[currow][curcol]=a;
a++;
}
}
for(currow=0;currow<N/2;currow++)//翻转中间列
{
for(curcol=N/4;curcol<N/4*3;curcol++)
{
temp = arr[currow][curcol];
arr[currow][curcol] = arr[N-currow-1][curcol];
arr[N-currow-1][curcol] = temp;
}
}
for(curcol=0;curcol<N/2;curcol++)//翻转中间行
{
for(currow=N/4;currow<N/4*3;currow++)
{
temp = arr[currow][curcol];
arr[currow][curcol] = arr[N-currow-1][curcol];
arr[N-currow-1][curcol] = temp;
}
}
for(int i=0;i<ROW;i++)
{
for(int j=0;j<COL;j++)
{
printf("%-2d ",arr[i][j]);
}
printf("\n");
}
}
运行结果为;
单偶: 阶数n = 4 * m + 2(m =1,2,3……)的魔方规律如下:
- 将魔方分成A、B、C、D四个k阶方阵,这四个方阵都为奇方阵,利用上面讲到的方法依次将A、D、B、C填充为奇魔方。
- 交换A、C魔方元素,对魔方的中间行,交换从中间列向右的m列各对应元素;对其他行,交换从左向右m列各对应元素。
- 交换B、D魔方元素,交换从中间列向左m – 1列各对应元素。
# include<stdio.h>
#define N 6
void MagicSquare()
{
#define ROW N
#define COL ROW
int arr[ROW][COL] = {0};//将数组全部置为0
int temp;
int k;
int a;
int currow;
int curcol;
k=N/2;
curcol=(k-1)/2;
currow=0;
arr[currow][curcol]=1;
//生成魔方阵A
for(a=2;a<k*k;a++)
{
if((a-1)%k==0)//前一个数是3的倍数
{
currow++;
}
else
{
currow--;
currow = (currow+k)%k;
curcol ++;
curcol %= k;
}
arr[currow][curcol]=a;
}
//根据A生产B、C、D魔方
for(currow = 0;currow < k; currow++)
{
for(curcol = 0;curcol < k; curcol++)
{
arr[currow+k][curcol+k] = arr[currow][curcol] + k*k;
arr[currow][curcol+k] = arr[currow][curcol] + 2*k*k;
arr[currow+k][curcol] = arr[currow][curcol] + 3*k*k;
}
}
for(currow = 0;currow < k;currow++)
{
if(currow == k / 2)
{
for(curcol = k / 2; curcol < k - 1; curcol++)
{
temp = arr[currow][curcol];
arr[currow][curcol] = arr[currow + k][curcol];
arr[currow + k][curcol] = temp;
}
}
else
{
for(curcol = 0;curcol < k / 2;curcol++)
{
temp = arr[currow][curcol];
arr[currow][curcol] = arr[currow + k][curcol];
arr[currow + k][curcol] = temp;
}
}
}
for(currow = 0; currow < k;currow++)
{
for(a = 0;a < (k - 1)/2 - 1;a++)
{
temp = arr[currow][k+ k/2 - a];
arr[currow][k+ k /2 -a] = arr[currow + k][k+k/2 -a];
arr[currow + k][k+k/2 -a] = temp;
}
}
for(int i=0;i<ROW;i++)
{
for(int j=0;j<COL;j++)
{
printf("%-2d ",arr[i][j]);
}
printf("\n");
}
}
int main()
{
MagicSquare();
return 0;
}
运行结果为: