魔方阵算法及C语言实现

1 魔方阵概念

魔方阵是指由123……n2填充的,每一行每一列对角线之和均相等的方阵,阶数n = 345…。魔方阵也称为幻方阵

例如三阶魔方阵为:

正在上传…重新上传取消

魔方阵有什么的规律呢?

魔方阵分为奇幻方和偶幻方。而偶幻方又分为是4的倍数(如4812……)和不是4的倍数(如61014……)两种。下面分别进行介绍。

2 奇魔方的算法

2.1 奇魔方的规律与算法

奇魔方(阶数n = 2 * m + 1m =123……)规律如下:

  1. 数字1位于方阵中的第一行中间一列;
  2. 数字a1 < a  ≤ n2)所在行数比a-1行数少1,若a-1的行数为1,则a的行数为n
  3. 数字a1 < a  ≤ n2)所在列数比a-1列数大1,若a-1的列数为n,则a的列数为1
  4. 如果a-1n的倍数,则a1 < a  ≤ n2)的行数比a-1行数大1,列数与a-1相同。

2.2 奇魔方算法的C语言实现

 1 #include <stdio.h> 2 // Author: http://furzoom.com/ 3 // N为魔方阶数 4 #define N 11 5   6 int main() 7 { 8     int a[N][N]; 9     int i;10     int col,row;11  12     col = (N-1)/2;13     row = 0;14  15     a[row][col] = 1;16  17     for(i = 2; i <= N*N; i++)18     {19         if((i-1)%N == 0 )20         {21             row++;22         }23         else24         {25             // if row = 0, then row = N-1, or row = row - 126             row--;27             row = (row+N)%N;28  29             // if col = N, then col = 0, or col = col + 130             col ++;31             col %= N;32         }33         a[row][col] = i;34     }35     for(row = 0;row<N;row++)36     {37         for(col = 0;col < N; col ++)38         {39             printf("%6d",a[row][col]);40         }41         printf("\n");42     }43     return 0;44 }

3 偶魔方的算法

偶魔方的情况比较特殊,分为阶数n = 4 * mm =123……)的情况和阶数n = 4 * m + 2m = 123……)情况两种。

3.1 阶数n = 4 * mm =123……)的魔方(双偶魔方)

算法1阶数n = 4 * mm =123……)的偶魔方的规律如下:

  1. 按数字从小到大,即123……n2顺序对魔方阵从左到右,从上到下进行填充;
  2. 将魔方中间n/2列的元素上、下进行翻转;
  3. 将魔方中间n/2行的元素左、右进行翻转。

C语言实现

 1 #include <stdio.h> 2 // Author: http://furzoom.com/ 3 // N为魔方阶数, 4 #define N 12 5   6 int main() 7 { 8     int a[N][N];//存储魔方 9     int i, temp;//临时变量10     int col, row;//col 列,row 行11  12     //初始化13     i = 1;14     for(row = 0;row < N; row++)15     {16         for(col = 0;col < N; col ++)17         {18             a[row][col] = i;19             i++;20         }21     }22  23     //翻转中间列24     for(row = 0; row < N/2; row ++)25     {26         for(col = N/4;col < N/4*3;col ++)27         {28             temp = a[row][col];29             a[row][col] = a[N-row-1][col];30             a[N-row-1][col] = temp;31         }32     }33  34     //翻转中间行35     for(col = 0; col < N/2; col ++)36     {37         for(row = N/4;row < N/4 * 3;row ++)38         {39             temp = a[row][col];40             a[row][col] = a[row][N-col-1];41             a[row][N-col-1] = temp;42         }43     }44  45     for(row = 0;row < N; row++)46     {47         for(col = 0;col < N; col ++)48         {49             printf("%5d",a[row][col]);50         }51         printf("\n");52     }53     return 0;54 }

算法2:阶数n = 4 * mm =123……)的偶魔方的规律如下:

  1. 按数字从小到大,即123……n2顺序对魔方阵从左到右,从上到下进行填充;
  2. 将魔方阵分成若干个4×4子方阵,将子方阵对角线上的元素取出;
  3. 将取出的元素按从大到小的顺序依次填充到n×n方阵的空缺处。

C语言实现

 1 #include <stdio.h> 2 // Author: http://furzoom.com/ 3 // N为魔方阶数 4 #define N 12 5   6 int main() 7 { 8     int a[N][N];//存储魔方 9     int temparray[N*N/2];//存储取出的元素10     int i;//循环变量11     int col, row;// col 列,row 行12  13     //初始化14         i = 1;15         for(row = 0;row < N; row++)16         {17             for(col = 0;col < N; col ++)18             {19                 a[row][col] = i;20                 i++;21             }22         }23     //取出子方阵中对角线上的元素,且恰好按从小到大的顺序排放24     i = 0;25     for(row = 0;row < N; row++)26     {27         for(col = 0;col < N; col ++)28         {29              if((col % 4 == row % 4) || ( 3 == ( col % 4 + row % 4)))30             {31                 temparray[i] = a[row][col];32                 i++;33             }34         }35     }36     //将取出的元素按照从大到小的顺序填充到n×n方阵中37     i = N*N/2 -1;38     for(row = 0;row < N; row++)39     {40         for(col = 0;col < N; col ++)41         {42             if((col % 4 == row % 4) || ( 3 == ( col % 4 + row % 4)))43             {44                 a[row][col] = temparray[i];45                 i--;46             }47         }48     }49     //输出方阵50     for(row = 0;row < N; row++)51     {52         for(col = 0;col < N; col ++)53         {54             printf("%5d",a[row][col]);55         }56         printf("\n");57     }58     return 0;59 }

3.2 阶数n = 4 * m + 2m =123……)的魔方(单偶魔方)

算法

k = 2 * m + 1;单偶魔方是魔方中比较复杂的一个。

  1. 将魔方分成ABCD四个k阶方阵,如下图正在上传…重新上传取消这四个方阵都为奇方阵,利用上面讲到的方法依次将ADBC填充为奇魔方。
  2. 交换AC魔方元素,对魔方的中间行,交换从中间列向右的m列各对应元素;对其他行,交换从左向右m列各对应元素。
  3. 交换BD魔方元素,交换从中间列向左m – 1列各对应元素。

C语言实现

#include <stdio.h>// Author: http://furzoom.com/// N为魔方阶数#define N 10
 int main()
{
    int a[N][N] = { {0} };//存储魔方
    int i,k,temp;
    int col,row;// col 列,row 行
 
    //初始化
    k = N / 2;
    col = (k-1)/2;
    row = 0;
    a[row][col] = 1;
    //生成奇魔方A
    for(i = 2; i <= k*k; i++)
    {
        if((i-1)%k == 0 )//前一个数是3的倍数        {
            row++;
        }
        else
        {
            // if row = 0, then row = N-1, or row = row - 1
            row--;
            row = (row+k)%k;
 
            // if col = N, then col = 0, or col = col + 1
            col ++;
            col %= k;
        }
        a[row][col] = i;
    }
 
    //根据A生成B、C、D魔方
    for(row = 0;row < k; row++)
    {
        for(col = 0;col < k; col ++)
        {
            a[row+k][col+k] = a[row][col] + k*k;
            a[row][col+k] = a[row][col] + 2*k*k;
            a[row+k][col] = a[row][col] + 3*k*k;
        }
    }
 
    // Swap A and C
    for(row = 0;row < k;row++)
    {
        if(row == k / 2)//中间行,交换从中间列向右的m列,N = 2*(2m+1)        {
            for(col = k / 2; col < k - 1; col++)
            {
                temp = a[row][col];
                a[row][col] = a[row + k][col];
                a[row + k][col] = temp;
            }
        }
        else//其他行,交换从左向右m列,N = 2*(2m+1)        {
            for(col = 0;col < k / 2;col++)
            {
                temp = a[row][col];
                a[row][col] = a[row + k][col];
                a[row + k][col] = temp;
            }
        }
    }
 
    // Swap B and D
    for(row = 0; row < k;row++)//交换中间列向左m-1列,N = 2*(2m+1)    {
        for(i = 0;i < (k - 1)/2 - 1;i++)
        {
            temp = a[row][k+ k/2 - i];
            a[row][k+ k /2 -i] = a[row + k][k+k/2 -i];
            a[row + k][k+k/2 -i] = temp;
        }
    }
 
    //输出魔方阵
    for(row = 0;row < N; row++)
    {
        for(col = 0;col < N; col ++)
        {
            printf("%5d",a[row][col]);
        }
        printf("\n");
    }
 
    return 0;
}

==========================================》

#include <stdio.h>

#define N 16 //这里可以修改N的值,并且N只能为奇数

int main()

{

int a[N][N]={0},i,j,k,p,m,n;

p=1;

while(p==1

{

printf("Enter n1~%d): ",N-1);/*可以输入小于等于N-1的奇数*/

scanf("%d",&n);

if((n!=0)&&(n<N)&&(n%2!=0)) p=0;

}

i=n+1;

j=n/2+1; /*建立魔方阵*/

a[1][j]=1;

for(k=2;k<=n*n;k++)

{

i=i-1;

j=j+1;

if((i<1&&(j>n))

{

i=i+2;j=j-1;

}

else

{

if(i<1 i=n;

if(j>n) j=1;

}

if(a[i][j]==0) a[i][j]=k;

else

{

i=i+2;

j=j-1;

a[i][j]=k;

}

}

for(i=1;i<=n;i++)/*输出魔方阵*/

{

for(j=1;j<=n;j++)

printf("%4d",a[i][j]);

printf("\n");

}

}

1n的平方这几个数构成一个n阶魔方阵。

算法:

依以下法则,你可以很快的写出奇数阶幻方!当然,这种写法只是其中一个答案,而不是唯一答案。

1)将1填入第一行中间;

2)将每个数填在前一个数的右上方。

3)若该位置超出最上行,则改填在最下行的对应位置;

4)若该位置超出最右列,则该填在最左列的对应行位置;

5)若某元素填在第一行最右列,下一个数填在该数同列的下一行;

6)若某数已填好,但其右上角已填了其他数据,则下一个数填在该数同列的下一行位置。

#include<stdio.h>

void main()

{

int a[15][15]={0},i,j,m,n,temp,M;

printf("请输入一个3~15的奇数:\n");

scanf("%d",&M);

i=0;

j=M/2;

a[i][j]=1;

for(temp=2;temp<=M*M;temp++)

{

m=i;

n=j;

i--;

j++;

if(i<0)

i=M-1;

if(j>M-1

j=0;

if(a[i][j]!=0)

{

i=m+1,j=n;

a[i][j]=temp;

continue;

}

a[i][j]=temp;

}

printf("%d×%d魔方阵:\n",M,M);

for(i=0;i<M;i++)

{

for(j=0;j<M;j++)

printf("%4d",a[i][j]);

printf("\n");

}

}

//(求4的倍数阶幻方)

void main()

{

int i,j,x,y,n,t,k=1;

int a[100][100];

printf("请输入魔方阵的阶数n \n");

scanf("%d",&n);

printf("输出为:\n");

if(n%4==0)

{

for(i=0;i<n;i++)

for(j=0;j<n;j++)

{

a[i][j]=k;

k++;

}

x=n-1;

for(j=0;j<n/2;j++,x--)

{

for(i=0;i<n;i++)

if(i%4!=j%4&&(i+j)%4!=3

{

t=a[i][j];

a[i][j]=a[i][x];

a[i][x]=t;

}

}

x=n-1;

for(i=0;i<n/2;i++,x--)

{

for(j=0;j<n;j++)

if(i%4!=j%4&&(i+j)%4!=3

{

t=a[i][j];

a[i][j]=a[x][j];

a[x][j]=t;

}

}

for(i=0;i<n;i++)

{

for(j=0;j<n;j++)

printf("%-4d",a[i][j]);

printf("\n");

}

}

else printf("输入错误\n");

system("pause...");

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南抖北快东卫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值