在上一篇博客中,我们讨论了阶数为奇数,以及阶数为(4K)的魔方阵的排列规则,

本篇文章则对最后一种情况: 阶数n = 4K + 2 的魔方阵 排列规律 进行分析, 以及代码实现.让我们直接进入正题:

 1. 偶数阶魔方阵(n = 4*K + 2)

1.排列规律:(源自百度百科):

         1. 先将整个方阵划成田字型的四个2 k + 1阶的奇数阶小方阵

         2. 右半两个小方阵中大于k+2的列;

         3. 左半两个小方阵中( k + 1 , k + 1 )的格位;

         4. 左半两个小方阵中除了( k+1 , 1 )是指第一列第k+1行的格位之外,小于k +1的列。

    (这个地方有误,应该为(k+1,k-1)的格位,否则在k = 2 即10阶魔方阵 会出错 (ps: 我只实验6阶 10 阶) 有可能在更高阶时(k+1,k-1)也不对)) 

         

    5. 以奇数阶魔方阵的方法连续填制法依左上、右下、右上、左下的顺序分别填制这四个小方阵。

         6. 将上半及下半方阵中有注记的数字对调,魔方阵完成。

 

2. 规律解读:

   我们可以将排列规律分成两个部分,

左上、右下、右上、左下的顺序分别以奇数魔方阵的摆放规则进行摆放(注意 : 在填写时要接上上个魔方阵的最后一个数字开始填起),

进行标记

 

  3. 图示:(在这里以6阶魔方阵为例)

   1.分块:

  

神奇魔方阵python代码 神奇魔方怎么玩_i++

 

   2. 按照 左上、右下、右上、左下的顺序分别以奇数魔方阵的摆放规则进行摆放 , 同时标记:

   

神奇魔方阵python代码 神奇魔方怎么玩_代码实现_02

 

   3.对标记的方块进行对调,魔方阵完成:

  

神奇魔方阵python代码 神奇魔方怎么玩_神奇魔方阵python代码_03

 

4.代码实现:

  根据上面的分析,代码主要分为两部分 1. 分块填数, 2. 交换

  代码如下:(软件:VS2019)

 

#include<assert.h>
#include<stdio.h>

void Print(int(*ar)[10], int row, int col)//打印
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            printf("%3d", ar[i][j]);
        }
        printf("\n");
    }
}


//传入 奇数阶小魔方阵起始的行列信息,以及小魔方阵的大小,起始的数字
void Magic_Square_1(int (*ar)[10],int row, int col, int size, int num)
{
    assert(ar != nullptr && row >= 0 && col >= 0);
    ar[row][size / 2 + col] = num;//注意第一个数摆在魔方阵第row行中间的位置
                                  // 在这里不能取col/2,要取 size/2 + col;
    int preRow = row;//记录上一个数字的行列信息
    int preCol = size / 2 + col;

    for (int i = num +1; i < num + size * size; i++)
    {
        //重点:
        //注意在这里行列下标都需要加上传入的row 和 col 即在这里的preRow 和 preCol 记录的是相对与
        //坐标[row][col]的偏移量.
        if (ar[row + (preRow - 1 + size) % size][col + (preCol + 1) % size] == 0)
        {
            ar[row + (preRow - 1 + size) % size][col + (preCol + 1) % size] = i ;
            preRow = (preRow - 1 + size) % size;
            preCol = (preCol + 1) % size;
        }
        else
        {
            ar[row + (preRow + 1) % size][col + preCol] = i;
            preRow = (preRow + 1) % size;
        }
    }
}

void Swap(int* pa, int* pb)
{
    int tmp = *pa;
    *pa = *pb;
    *pb = tmp;
}

void Magic_Square()
{
#define ROW 10
#define COL ROW
    if ((ROW - 2) % 4 != 0) return;
    int ar[ROW][COL] = {};
    
    
    Magic_Square_1(ar,   0,     0,    ROW / 2,              1);//左上
    Magic_Square_1(ar, ROW/2, COL/2,  ROW / 2,  1+(ROW*COL/4));//右下     可以让第一个小魔方阵的每个数加上 ROW*COl/4就可以得到
    Magic_Square_1(ar,   0,   COL/2,  ROW / 2,  1+ (ROW * COL / 2));//右上    同理 让第二个小魔方阵加上 ROW*COL /4 就可得到
    Magic_Square_1(ar, ROW/2,    0,   ROW / 2,  1+ (ROW * COL / 4)*3);//左下     同上

    //上下对调右半两个小方阵中大于k+2的列;
    int k = (ROW - 2) / 4;
for (int i = 0; i < ROW/2; i++)
    {
        for (int j = 0; j < COL; j++)
        {
            //上下对调右半两个小方阵中大于k+2的列;注意在程序中下标是从零开始的,所以不需要加1
            if (j > (k + ROW/2 + 1)) // 此处 注意需要加上  ROW/2
            {
                Swap(&ar[i][j], &ar[i + ROW / 2][j]);
            }

            
            //左半两个小方阵中小于k +1的列。
            if(j < k )//此处注意在程序中,下标是从零开始的,所以不需要加1 即:if(j < (k + 1)) 这样反而是错误的
            {
                Swap(&ar[i][j], &ar[i + ROW / 2][j]);
            }
        }
    }

    // (k+1,k-1) 这个格位不能交换,所以交换回来
    Swap(&ar[k][k - 1], &ar[k + ROW / 2][k - 1]);

    //对调左半两个小方阵中( k + 1 , k + 1 )的格位;
    Swap(&ar[k][k], &ar[k + ROW / 2][k]);

    Print(ar, ROW, COL);

#undef ROW
#undef COL

}

int main()
{
    Magic_Square();
    return 0;
}

 

 

运行结果:

神奇魔方阵python代码 神奇魔方怎么玩_代码实现_04

 

 

 验证:

 

神奇魔方阵python代码 神奇魔方怎么玩_代码实现_05

 

 

 

 

(若有大哥发现其中的不合适或者错误,请务必在评论中告知,小弟在这里祝大哥心情愉悦,生活快乐!)

 

 

本篇完.