http://noi.openjudge.cn/ch0108/22/
- 总时间限制:
- 1000ms
- 内存限制:
- 65535kB
- 描述
-
幻方是一个很神奇的N*N矩阵,它的每行、每列与对角线,加起来的数字和都是相同的。
我们可以通过以下方法构建一个幻方。(阶数为奇数)
1.第一个数字写在第一行的中间
2.下一个数字,都写在上一个数字的右上方:
a.如果该数字在第一行,则下一个数字写在最后一行,列数为该数字的右一列
b.如果该数字在最后一列,则下一个数字写在第一列,行数为该数字的上一行
c.如果该数字在右上角,或者该数字的右上方已有数字,则下一个数字写在该数字的下方 - 输入
- 一个数字N(N<=20)
- 输出
- 按上方法构造的2N-1 * 2N-1的幻方
- 样例输入
-
3
- 样例输出
-
17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
解析:按照题目的意思,假如a[i][j]=t,那么下一个要填写进去的t+1的坐标首先考虑是x=i-1,y=j+1,但是假如i==0&&j==2*n-1或者a[x][y]已经被占用的时候,应该放在a[i][j]的正下方。
所以代码就是:
1 #include<stdio.h> 2 #include<stdlib.h> 3 int main(int argc, char *argv[]) 4 { 5 int n,i,j,t; 6 int **a; 7 long nn,len; 8 int x,y; 9 10 scanf("%d",&n); 11 len=2*n-1; 12 a=(int**)malloc(sizeof(int*)*len); 13 for(i=0;i<len;i++) 14 a[i]=(int*)malloc(sizeof(int)*len); 15 16 for(i=0;i<len;i++) 17 for(j=0;j<len;j++) a[i][j]=0; 18 19 i=0; 20 j=(n*2-1)/2; 21 t=1; 22 a[i][j]=t; 23 nn=len*len; 24 while(t<nn) 25 { 26 t++; 27 x=(i-1+len)%len; 28 y=(j+1)%len; 29 if(i==0&&j==len||a[x][y]!=0) 30 { 31 x=i+1; 32 y=j; 33 } 34 a[x][y]=t; 35 i=x; 36 j=y; 37 } 38 39 for(i=0;i<len;i++) 40 { 41 for(j=0;j<len;j++) 42 { 43 printf("%d ",a[i][j]); 44 } 45 printf(" "); 46 } 47 return 0; 48 }
额其实应该要写free()释放内存的,有点懒,没写。貌似也能够通过OJ的检查O(∩_∩)O