该程序实现了输入一个正的奇数n,输出一个n阶幻方的解(解不唯一,但是该程序只输出一个解)。
幻方是最古老且最流行的数学游戏之一,它曾激起很多重要历史名人的兴趣。一个n阶幻方就是由一个整数1,2,3,·······,n^2按照下面的方式构成的n*n阶矩阵:
它的每一行和每一列以及两条对角线上的数字总和相等,都等于某个整数s,这个s被称为这个幻方的幻和。
n 阶幻和中所有整数的和是1+2+3·······+n^2 = n^2*(n^2+1)/2.
所以s =n*(n^2+1)/2.
这是La Loubere在17世纪发现幻方的构造方法。(局限于n是奇数)
首先把1放到第一行的中间,其后面的整数(从2开始),按照他们的自然顺序放置在从左下角到右上角的斜对角线上,并做如下修正:
(1)到了第一行时,列数往右移1列,行数变为最后一行。
(2)到了最右一列时,行数往上移一行,列数变为最左边一列
(3)到了幻方的右上角或者该方格已经被填上了数字,那么列数不变,行数往下移一行。
贴代码:
View Code
1 //输入一个正的奇数n,将输出一个n阶幻方,输入-1程序结束,输入的 2 #include <cstdio> 3 #include <stdlib.h> 4 #include <cstring> 5 #define MAXN 1000 6 int a[MAXN][MAXN]; 7 int n; 8 int main() 9 { 10 while(1) 11 { 12 printf("\033[2J\033[1050Aplease inter an odd which is greater than 0:\n"); 13 int n; 14 scanf("%d",&n); 15 if(n%2==0 || n<0) 16 { 17 printf("sorry ,your number is invalid\n"); 18 printf("do you want to inter an new number?\n"); 19 printf("if your answer is yes,enter 1,else enter 0\n"); 20 int flag; 21 scanf("%d",&flag); 22 if(flag) 23 continue; 24 else 25 break; 26 } 27 int cnt =0; 28 int i=0,j=n/2; 29 memset(a,0,sizeof(a)); 30 while(1)//核心代码在这里,就是这个while()循环 31 { 32 if(cnt == n*n) break; 33 a[i][j] = ++cnt; 34 int ii= i-1; 35 int jj=j+1; 36 if(ii < 0 && jj >= n) 37 i = i+1; 38 else if(ii <0) 39 { 40 i = n-1; 41 j = jj; 42 } 43 else if(jj >=n) 44 { 45 i = i- 1; 46 j = 0; 47 } 48 else if(a[ii][jj] > 0)//该位置已经填了数字了 49 i = i+1; 50 else 51 { 52 i = ii; 53 j = jj; 54 } 55 } 56 for(int i=0; i<n; ++i) 57 { 58 for(int j=0; j<n; ++j) 59 printf("%-4d ",a[i][j]); 60 puts(""); 61 } 62 printf("do you want to play again?\n"); 63 printf("if your answer is yes,enter 1,else enter 0\n"); 64 int f; 65 scanf("%d",&f); 66 if(f) continue; 67 else break; 68 } 69 printf("\033[2J\033[1050Athe game is ended,thanks\n"); 70 return 0; 71 }