当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

关于魔方阵的解法

    首先把从1~n2的整数按从小到大的顺序排列成一个n×n的方阵A进行观察。(本文中所有n都是指大于1的奇数,下文中均以“A”代表这类顺序排列的n×n方阵)
    以5阶阵为例:以下是A方阵
    1  2  3  4  5
    6  7  8  9  10
    11 12 13 14 15
    16 17 18 19 20
    21 22 23 24 25
    下边是魔方阵B:
    12 16 25 4  8
    6  15 19 23 2
    5  9  13 17 21
    24 3  7  11 20
    18 22 1  10  14
    先假设n阶奇次魔方阵B是存在的,从A中可以看出,B的任一元素在A中都有唯一确定的行号和列号组合(y,x)。
    分离出B中所有元素在A中的行号y来构成n×n方阵I,让I(i,j)等于从B(i,j)分离出来的y;(如I(1,1) =3,即12在A中的行号A(3,2);I(1,2)=4,即16在A中的行号A(4,1)。)以下是I方阵:
    3  4  5  1  2
    2  3  4  5  1
    1  2  3  4  5
    5  1  2  3  4
    4  5  1  2  3
    同样分离出B中所有元素在A中的列号y来构成n×n方阵J,让J(i,j)等于从B(i,j)分离出来的x。以下是J方阵
    2  1  5  4  3
    1  5  4  3  2
    5  4  3  2  1
    4  3  2  1  5
    3  2  1  5  4
    观察方阵I特征为:

            1.组成方阵的数为1~n的整数;

            2.任一行、列均遍历1~n的所有整数;

            3.主对角线上的数均为(n+1)/2,辅对角线遍历1~n的所有整数。

    方阵J特征前两点同I,区别是第三点,辅对角线上的数均为(n+1)/2,主对角线遍历1~n的所有整数。 另外还有容易忽略的一点,I、J方阵对应位置上的数字组合[I(i,j),J(i,j)]是唯一的。
           综合以上的结论可以知道:B(i,j)=(I(i,j)-1)×n+J(i,j)。所以只要构造出这样两个只含1~n的数的方阵I和J,就可以确定一个n×n的魔方阵。
    现在,问题就转化为怎样构造分别满足I和J的特征的两个n×n方阵。其实完成这样的算法是很简单的,可以按以下方法实现:

    1) 方阵I的第一行由(n+1)/2打头,后面依次为前一个数关于n的循环后继;

    2)方阵I的第i+1行由第i行循环右移得到。

    本人给出的程序:

    main()
    {
    int n,i,j;
    int a[20][20],x[20][20],y[20][20];/* a数组为最后结果数组文中的B方阵,X,Y分别是文中提到的数组I,J*/
    printf("please input the number:");
    scanf("%d",&n); /*输入需要的数组维数*/
     x[0][0]=(n+1)/2;
     for(j=1;j<n;j++)
      {
       if(x[0][j-1]==n) x[0][j]=x[0][j-1]+1-n;
       else            x[0][j]=x[0][j-1]+1;
     }/*给x中的第一行元素赋值*/

 

共2页 首页 上一页 1 2 下一页 尾页 跳转到
上一篇:孔明棋的小程序 下一篇:集邮问题
相关内容
赞助商链接