正文

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

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

分享到:

构造n阶魔方阵

何谓魔方阵?
4 9 2
3 5 7
8 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分别表示上述三种情况对应的构造函数。

  1. #include     
  2. #define 520    
  3.   
  4. int num[N][N];   
  5.   
  6. void n1(int n)    
  7.   
  8.     int i,j,count=0;    
  9.     for(i=0,j=(n-1)/2;count<>
  10.        
  11.         count++;    
  12.         num[i][j]=count;    
  13.         if(count%n==0)    
  14.            
  15.             i++;    
  16.            
  17.         else    
  18.            
  19.             i--;    
  20.             j++;    
  21.            
  22.         if(i<0)    
  23.             i+=n;    
  24.         if(j>=n)    
  25.             j-=n;    
  26.        
  27.     for(i=0;i<>
  28.          
  29.         for(j=0;j<>
  30.               
  31.             printf("%d ",num[i][j]);       
  32.               
  33.         printf("%d\n",num[i][n-1]);      
  34.          
  35.   
  36.   
  37. void n2(int n)    
  38.   
  39.     int i,j,k,t;   
  40.     for(i=1;i<=n;i+=4)   
  41.     for(j=1;j<=n;j+=4)   
  42.     {   
  43.         for(k=0;k<4;k++)   
  44.         {   
  45.             num[i+k][j+k] 1;   
  46.             num[i+k][j+3-k] 1;   
  47.         }   
  48.     }   
  49.     0;   
  50.     for(i=1;i<=n;i++)   
  51.     for(j=1;j<=n;j++)   
  52.     {   
  53.         t++;   
  54.         if(num[i][j]) num[i][j] t;   
  55.     }   
  56.     0;   
  57.     for(i=n;i>=1;i--)   
  58.     for(j=n;j>=1;j--)   
  59.     {   
  60.         t++;   
  61.         if(num[i][j]==0) num[i][j] t;   
  62.     }   
  63.   
  64.     for(i=1;i<=n;i++)       
  65.          
  66.         for(j=1;j<>
  67.               
  68.             printf("%d ",num[i][j]);       
  69.               
  70.         printf("%d\n",num[i][n]);      
  71.          
  72.   
  73.   
  74. void n3(int n)    
  75.   
  76.     int i,j,m,t,v,count=0;    
  77.     v=(n+2)/4;    
  78.     m=n/2;    
  79.     for(i=0,j=(m-1)/2;count<>
  80.        
  81.         count++;    
  82.         num[i][j]=count;    
  83.         if(count%m==0)    
  84.             i++;    
  85.         else    
  86.                
  87.             i--;    
  88.             j++;    
  89.                
  90.         if(i<0)    
  91.             i+=m;    
  92.         if(j>=m)    
  93.             j-=m;    
  94.        
  95.     for(i=m,j=(m-1)/2+m;count<2*m*m;)    
  96.        
  97.         count++;    
  98.         num[i][j]=count;    
  99.         if(count%m==0)    
  100.             i++;    
  101.         else    
  102.            
  103.             i--;    
  104.             j++;    
  105.            
  106.         if(i<>
  107.             i+=m;    
  108.         if(j>=2*m)    
  109.             j-=m;    
  110.        
  111.     for(i=0,j=(m-1)/2+m;count<3*m*m;)    
  112.        
  113.         count++;    
  114.         num[i][j]=count;    
  115.         if(count%m==0)    
  116.             i++;    
  117.         else    
  118.            
  119.             i--;    
  120.             j++;    
  121.            
  122.         if(i<0)    
  123.             i+=m;    
  124.         if(j>=2*m)    
  125.             j-=m;    
  126.        
  127.     for(i=m,j=(m-1)/2;count<4*m*m;)    
  128.        
  129.         count++;    
  130.         num[i][j]=count;    
  131.         if(count%m==0)    
  132.             i++;    
  133.         else    
  134.            
  135.             i--;    
  136.             j++;    
  137.            
  138.         if(i<>
  139.             i+=m;    
  140.         if(j>=m)    
  141.             j-=m;    
  142.        
  143.     for(i=0;i<>
  144.        
  145.         for(j=0;jn-v+1;j++)    
  146.            
  147.             t=num[i][j];    
  148.             num[i][j]=num[i+m][j];    
  149.             num[i+m][j]=t;    
  150.            
  151.         for(j=n-v+2;j<>
  152.            
  153.             t=num[i][j];    
  154.             num[i][j]=num[i+m][j];    
  155.             num[i+m][j]=t;    
  156.            
  157.        
  158.     t=num[v-1][0];    
  159.     num[v-1][0]=num[v+m-1][0];    
  160.     num[v+m-1][0]=t;    
  161.     t=num[v-1][v-1];    
  162.     num[v-1][v-1]=num[v+m-1][v-1];    
  163.     num[v+m-1][v-1]=t;    
  164.     for(i=0;i<>
  165.          
  166.         for(j=0;j<>
  167.               
  168.             printf("%d ",num[i][j]);       
  169.               
  170.         printf("%d\n",num[i][n-1]);      
  171.          
  172. }   
  173.   
  174. int main()    
  175.   
  176.     int n;    
  177.     scanf("%d",&n);    
  178.     if((n%2)!=0)    
  179.         n1(n);    
  180.     else if((n%4)==0)    
  181.         n2(n);    
  182.     else    
  183.         n3(n);    
  184.     return 0;   
  185.  

 参考资料:http://residence.educities.edu.tw/oddest/index.htm

阅读(4119) | 评论(0)


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

评论

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