对于魔方阵,我们得考虑一下它的偶数阶和奇数阶是否是同一个规则呢?从平常我们写的魔方阵可以看出,偶数阶的和奇数阶的规则是不一样的,因此,在本文从两个角度来分析魔方阵,但是偶数阶中,我们又可以发现,偶数阶中又分为能被4整除和可以被2整除且不能被4整除的矩阵。
1. 奇数阶魔方阵的排列规律(n=2k+1)
(1) 首先将数字1放在第1行中间1列(在程序中可以先特殊处理,直接令这一个位置值为1)
(2) 从数字2开始直到n×n止,其余各数依次按这样的规则:每一个数存放的行比前一个数的行数减1,列数加1(例如上面的三阶魔方阵,5在4的上一行后一列);
(3) 如果上一个数的行数为1,则下一个数的行数为n(指最下一行)(例如1在第一行,则2应放在最下一行,列数同样加1)
(4) 当上一个数的列数为n时,下一个数的列数应为1,行数减去1。(例如2在第3行最后一列,则3应放在第二行第一列)
(5) 如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面(例如按上面的规定,4应该放在第1行第2列,但该位置已经被占据,所以4就放在3的下面)
代码:
#include<stdio.h>
#include<assert.h>
void Magic1()
{
#define ROW 5
#define COL ROW
assert(ROW % 2 != 0);
int arr[ROW][COL] = { 0 };
int currow = 0;
int curcol = COL / 2;
arr[currow][curcol] = 1;
for (int i = 2; i <= ROW * COL; i++)
{
if (arr[(currow - 1 + ROW) % ROW][(curcol + 1) % COL] == 0)
{
currow = (currow - 1 + ROW) % ROW;
curcol = (curcol + 1) % COL;
}
else
{
currow = (currow + 1) % ROW;
}
arr[currow][curcol] = i;
}
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
printf("%-3d", arr[i][j]);
}
printf("\n");
}
#undef ROW
#undef COL
}
int main()
{
Magic1();
return 0;
}
运行结果:
2. 偶数阶魔方阵
2.1 能被4整除的偶数阶魔方阵规律(n=4k)
(1) 先将整个方阵划分成k*k个4阶方阵,然后在每个4阶方阵的对角线上做记号
(2) 由左而右、由上而下,遇到没有记号的位置才填数字,但不管是否填入数字,每移动一格数字都要加1
(3) 自右下角开始,由右而左、由下而上,遇到没有数字的位置就填入数字,但每移动一格数字都要加1
代码:
#include<stdio.h>
#include<assert.h>
void Magic2()
{
#define ROW 8
#define COL ROW
assert(ROW % 2 == 0 && ROW % 4 == 0);
int arr[ROW][COL] = { 0 };
int tmp = 1;
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
arr[i][j] = tmp++;
}
}
int row1 = 0;//主对角线行
int col1 = 0;//主对角线列
int row2 = 0;//副对角线行
int col2 = 0;//副对角线列
//总体划分K*K块(i*j)
for (int i = 0; i < (ROW / 4); i++)//i指向行
{
for (int j = 0; j < COL / 4; j++)//j指向列
{
row1 = 4 * i;
col1 = 4 * j;
row2 = 4 * i;
col2 = 4 * j + 3;
for (int k = 0; k < 4; k++)
{
arr[row1][col1] = (ROW * COL + 1) - arr[row1][col1];
arr[row2][col2] = (ROW * COL + 1) - arr[row2][col2];
row1++;
col1++;
row2++;
col2--;
}
}
}
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
printf("%-3d", arr[i][j]);
}
printf("\n");
}
#undef ROW
#undef COL
}
int main()
{
Magic2();
return 0;
}
运行结果:
2.1 能被2整除且不能被4整除的偶数阶魔方阵规律(n=4k+2)
在填充魔方阵时,先将整个方阵划成田字型的4个2k+ 1阶的奇数阶小方阵,并以下列规则法做标记:(这里下标是从0开始)
(1) 右半两个小方阵中大于k+2的列。
(2) 左半两个小方阵中( k + 1 , k + 1 )的格位。
(3) 左半两个小方阵中除了( 1 , k + 1 )是指第一列第k+1行的格位之外,小于k +1的列。
以奇数阶魔方阵的方法连续填制法依左上、右下、右上、左下的顺序分别填制这四个小方阵,然后
将上半及下半方阵中有标记的数字对调,可得到魔方阵
代码:
#include<stdio.h>
#include<assert.h>
void Magic3()
{
#define ROW 6
#define COL ROW
assert(ROW % 2 == 0 && ROW % 4 != 0);
int tmp = 0;
int arr[ROW][COL] = { 0 };
int currow = 0;
int curcol = COL / 4;
arr[currow][curcol] = 1;
//左上角矩阵
for (int i = 2; i <= ROW * COL / 4; i++)
{
if (arr[(currow - 1 + ROW / 2) % (ROW / 2)][(curcol + 1) % (COL / 2)] == 0)
{
currow = (currow - 1 + ROW / 2) % (ROW / 2);
curcol = (curcol + 1) % (COL / 2);
}
else
{
currow = (currow + 1) % (ROW / 2);
}
arr[currow][curcol] = i;
}
//右下角矩阵(根据左上角矩阵,观察可看出,左上角矩阵每个元素加9就是右下角矩阵中的元素)
currow = ROW / 2;
for (int i = 0; i < ROW / 2; i++, currow++) //i和j指向左上角
{
curcol = COL / 2;
for (int j = 0; j < COL / 2; j++, curcol++)
{
arr[currow][curcol] = arr[i][j] + (ROW * COL / 4);
}
}
//右上角矩阵(根据右下角矩阵计算,也是每个元素加9就是右上角矩阵中的元素)
currow = 0;
for (int i = ROW / 2; i < ROW; i++, currow++) //i和j指向右下角
{
curcol = COL / 2;
for (int j = COL / 2; j < COL; j++, curcol++)
{
arr[currow][curcol] = arr[i][j] + (ROW * COL / 4);
}
}
//左下角(根据右上角矩阵中的元素加9来计算左下角矩阵中的元素)
currow = ROW / 2;
for (int i = 0; i < ROW / 2; i++, currow++) //i和j指向右上角
{
curcol = 0;
for (int j = COL / 2; j < COL; j++, curcol++)
{
arr[currow][curcol] = arr[i][j] + (ROW * COL / 4);
}
}
//右半边 大于k+2的列 进行上下交换
for (int i = 0; i < ROW / 2; i++)
{
for (int j = ROW / 2 + ROW / 4 + 2; j < COL; j++)
{
tmp = arr[i][j];
arr[i][j] = arr[i + ROW / 2][j];
arr[i + ROW / 2][j] = tmp;
}
}
//交换左半边,两个中心节点
tmp = arr[ROW / 4][COL / 4];
arr[ROW / 4][COL / 4] = arr[ROW / 4 + ROW / 2][COL / 4];
arr[ROW / 4 + ROW / 2][COL / 4] = tmp;
//左半边,除(K+1,1)这个点外,小于k+1的列 上下交换
for (int i = 0; i < ROW / 2; i++)
{
for (int j = 0; j < COL / 4; j++)
{
if (i == ROW / 4 && j == 0)
{
continue;
}
tmp = arr[i][j];
arr[i][j] = arr[i + ROW / 2][j];
arr[i + ROW / 2][j] = tmp;
}
}
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
printf("%-3d", arr[i][j]);
}
printf("\n");
}
#undef ROW
#undef COL
}
int main()
{
Magic3();
return 0;
}
运行结果:
以上就是魔方阵的所有代码,写错的请各位大佬指正!!!