实现n阶幻方
n为奇数 (n=3,5,7,9,11……) (n=2*k+1,k=1,2,3,4,5……)
奇数阶幻方最经典的填法是罗伯特法(也有人称之为楼梯方)。填写方法是这样:
把1(或最小的数)放在第一行正中; 按以下规律排列剩下的n*n-1个数:
(1)、每一个数放在前一个数的右上一格;
(2)、如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;
(3)、如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;
(4)、如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在前一个数的下一行同一列的格内;
(5)、如果这个数所要放的格已经有数填入,处理方法同(4)。
这种写法总是先向“右上”的方向,象是在爬楼梯。
代码如下:
1 // asdasdasdas.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <stdlib.h> 6 7 int _tmain(int argc, _TCHAR* argv[]) 8 { 9 //i为行 j为列 K即是小于n的平方的数 10 int a[20][20],i,j,k,n; 11 12 printf("输入一个大于3小于20的的奇数"); 13 scanf("%d",&n); 14 if((n<3)||(n%2==0)||(n>=20)) 15 { 16 printf("输入错误!"); 17 } 18 19 for(i=1;i<=n;i++) 20 for(j=1;j<=n;j++) 21 a[i][j]=0; 22 j=n/2+1; 23 //第一行居中位置为1 24 a[1][j]=1; 25 for(k=2;k<=n*n;k++) 26 { 27 //向右上方移动 即行数减一 列数加一(从上到下 从左到右依次增大) 28 i=i-1; 29 j=j+1; 30 //判断是不是移动时同时超过了第一行和最右边那列,即过了对角线 31 if((i<1)&&(j>n)) 32 { 33 //向下移动一行 34 i=i+2; 35 j=j-1; 36 } 37 else 38 { 39 //判断是不是过了第一行如果是就从最后一行开始 40 if(i<1) 41 i=n; 42 //判断是不是过了最后一列如果是就从第一列开始 43 if(j>n) 44 j=1; 45 } 46 //判断是不是要移动到的地方为空 47 if(a[i][j]==0) 48 a[i][j]=k; 49 //如果不是,和超过对角线处理方法一样 向下移动 50 //这里本来打算做成一个方法,这样两个就都能直接调用了 51 else 52 { 53 i=i+2; 54 j=j-1; 55 a[i][j]=k; 56 } 57 } 58 //输出 59 for(i=1;i<=n;i++) 60 { 61 for(j=1;j<=n;j++) 62 printf("%4d",a[i][j]); 63 printf("\n"); 64 } 65 system("pause"); 66 }
浙公网安备 33010602011771号