正文

构造n阶魔方阵2008-05-31 10:31:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/insky/35790.html

分享到:

构造n阶魔方阵 何谓魔方阵?4 9 23 5 78 1 6定义:由n*n个数字所组成的n阶方阵,具有各对角线,各横列与纵行的数字和都相等的性质,称为魔方阵。而这个相等的和称为魔术数字。若填入的数字是从1到n*n,称此种魔方阵为n阶正规魔方阵。   1.    n = 2k + 1(奇数时) (1)  1放在第一行的中间位置上; (2)  下一个数放在当前位置的上一行、下一列; (3)  若当前位置是第一行,下一个数放在最后一行;若当前位置是最后一列,下一个数放在第一列; (4)  若下一个数要放的位置上已经有了数字,则下一个数字放在当前位置的下一行,相同列。 根据此规则填充的3阶魔方阵如下: 8 1 6 3 5 7 4 9 2   2.    n = 4k(4的整数倍时) (1)  先将整个方阵划分成k*k个4阶方阵,然后在每个4阶方阵的对角线上做记号 (2)  由左而右、由上而下,遇到没有记号的位置才填数字,但不管是否填入数字,每移动一格数字都要加1 (3)  自右下角开始,由右而左、由下而上,遇到没有数字的位置就填入数字,但每移动一格数字都要加1 (2)后:                                  (3)后:       3.     n = 4k + 2本法填制魔方阵时,先将整个方阵划成田字型的四个2 k + 1阶的奇数阶小方阵,并以下法做注记:1,右半两个小方阵中大于k+2的行。2,左半两个小方阵中( k + 1 , k + 1 )的格位。3,左半两个小方阵中除了( 1 , k + 1 )的格位之外,小于k +1的行。以1的方法连续填制法依左上、右下、右上、左下的顺序分别填制这四个小方阵。将上半及下半方阵中有注记的数字对调,魔方阵完成。     左上          右下          右上            左下     123注记的内容调换      代码如下,n1 n2 n3分别表示上述三种情况对应的构造函数。 #include      #define N 520        int num[N][N];       void n1(int n)     {         int i,j,count=0;         for(i=0,j=(n-1)/2;count<>     {             count++;             num[i][j]=count;             if(count%n==0)             {                 i++;             }             else             {                 i--;                 j++;             }             if(i<0)                 i+=n;             if(j>=n)                 j-=n;         }         for(i=0;i<>     {               for(j=0;j<>         {                    printf("%d ",num[i][j]);                }                printf("%d\n",num[i][n-1]);           }       }        void n2(int n)     {         int i,j,k,t;        for(i=1;i<=n;i+=4)        for(j=1;j<=n;j+=4)        {            for(k=0;k<4;k++)            {                num[i+k][j+k] = 1;                num[i+k][j+3-k] = 1;            }        }        t = 0;        for(i=1;i<=n;i++)        for(j=1;j<=n;j++)        {            t++;            if(num[i][j]) num[i][j] = t;        }        t = 0;        for(i=n;i>=1;i--)        for(j=n;j>=1;j--)        {            t++;            if(num[i][j]==0) num[i][j] = t;        }           for(i=1;i<=n;i++)            {               for(j=1;j<>         {                    printf("%d ",num[i][j]);                }                printf("%d\n",num[i][n]);           }       }        void n3(int n)     {         int i,j,m,t,v,count=0;         v=(n+2)/4;         m=n/2;         for(i=0,j=(m-1)/2;count<>     {             count++;             num[i][j]=count;             if(count%m==0)                 i++;             else                 {                 i--;                 j++;                 }             if(i<0)                 i+=m;             if(j>=m)                 j-=m;         }         for(i=m,j=(m-1)/2+m;count<2*m*m;)         {             count++;             num[i][j]=count;             if(count%m==0)                 i++;             else             {                 i--;                 j++;             }             if(i<>             i+=m;             if(j>=2*m)                 j-=m;         }         for(i=0,j=(m-1)/2+m;count<3*m*m;)         {             count++;             num[i][j]=count;             if(count%m==0)                 i++;             else             {                 i--;                 j++;             }             if(i<0)                 i+=m;             if(j>=2*m)                 j-=m;         }         for(i=m,j=(m-1)/2;count<4*m*m;)         {             count++;             num[i][j]=count;             if(count%m==0)                 i++;             else             {                 i--;                 j++;             }             if(i<>             i+=m;             if(j>=m)                 j-=m;         }         for(i=0;i<>     {             for(j=0;jn-v+1;j++)             {                 t=num[i][j];                 num[i][j]=num[i+m][j];                 num[i+m][j]=t;             }             for(j=n-v+2;j<>         {                 t=num[i][j];                 num[i][j]=num[i+m][j];                 num[i+m][j]=t;             }         }         t=num[v-1][0];         num[v-1][0]=num[v+m-1][0];         num[v+m-1][0]=t;         t=num[v-1][v-1];         num[v-1][v-1]=num[v+m-1][v-1];         num[v+m-1][v-1]=t;         for(i=0;i<>     {               for(j=0;j<>         {                    printf("%d ",num[i][j]);                }                printf("%d\n",num[i][n-1]);           }       }       int main()     {         int n;         scanf("%d",&n);         if((n%2)!=0)             n1(n);         else if((n%4)==0)             n2(n);         else             n3(n);         return 0;    }    参考资料:http://residence.educities.edu.tw/oddest/index.htm

阅读(4169) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册