构造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

评论