幻方及编程.docx
《幻方及编程.docx》由会员分享,可在线阅读,更多相关《幻方及编程.docx(17页珍藏版)》请在冰点文库上搜索。
幻方及编程
奇数阶幻方的方法:
首先把1放在最上一行的正中间的方格,然后把下一个整数放置在右上方,如果到达最上一行,下一个整数放在最后一行,就好像它在第一行的上面,如果到达最有端,则下一个整数放在最左端,就好像好像他的最右端一样。
当到达方格中填上数时,下一个整数就放在刚填数的下面,照着三阶幻方,从1到9走一下,就可以明白它的构造方法。
8
1
6
3
5
7
4
9
2
偶阶幻方分为单偶阶和双偶阶:
1双偶阶幻方(对称交换)n为偶数,且能被4整除(n=4,8,12….)先说明一个定义,互补:
如果两个数字和,等于幻方的最大数和最和最小数的和,即n*n+1,称互补。
先看看四阶幻方的添法:
将数字从左到右;从上到下按顺序填写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
16
2
3
13
5
11
10
8
9
7
6
12
4
14
15
1
这个方正的对角线,已用颜色标出。
将对角线上的数字,换成与它互补的(同色)的数字。
这里,n*n+1=4*4+1=17;把1换成17-1=16;把6换成17-6=11;把11换成17-11=6……..换成后就是四阶幻方。
对于n=4m阶的幻方,我们先把把数字按顺序填写。
写好后,按4*4把它划分成m*m各方阵。
因为n是4的倍数,一定能用4*4的方阵分割。
然后把每个小方阵的对角线,像制作成四阶幻方地方法一样,对角线上的数字换成互补数字,就构成幻方。
64
2
3
61
60
6
7
57
9
55
54
12
13
51
50
16
17
47
46
20
21
43
42
24
40
26
27
37
36
30
31
33
32
34
35
29
28
38
39
25
41
23
22
44
45
19
18
48
49
15
14
52
53
11
10
56
8
58
59
5
4
62
63
1
2单偶阶幻方(不能被四整除的是单偶阶幻方)如6阶、10阶、14阶…将n阶单偶阶幻方表示为4m+2,将其等分成四分,成为如下图所示A、B、C、D四个2m+1的奇阶幻方。
AC
DB
A用1到(2m+1)^2填写成2m+1阶幻方,B用(2m+1)^2+1到2*(2m+1)^2填写成2m+1
阶幻方,C用2*(2m+1)^2+1到3*(2m+1)^2填写成2m+1阶幻方,D用3*(2m+1)^2
到4*(2m+1)^2填写成2m+1阶幻方。
【注:
^是平方的意思】
六阶幻方如下:
8
1
6
26
19
24
3
5
7
21
23
25
4
9
2
22
27
20
35
28
33
17
10
15
30
32
34
12
14
16
31
36
29
13
18
11
在A每行取m个小格(中心格及一侧对角线格为必换格,其余m-1格只要不是对角线格即可)也就是说在A中间一行取包裹中心格在内的第m个小格,其它行左侧边缘取m个小格,
将其与D中对应得方格交换;B与C任取m-1列进行交换6阶幻方就是4*1+2,那么m就是1在A中间一行取中心格1个小格,将其与D中相应方格进行交换,B与C接近右侧m-1列进行交换(6阶幻方m-1=0故不用交换)。
如下图用Strachey法生成的6阶幻方:
35
1
6
26
19
24
3
32
7
21
23
25
31
9
2
22
27
20
8
28
33
17
10
15
30
5
34
12
14
16
4
36
29
13
18
11
下面是一个关于上述幻方的编程:
【注:
数不能太大】
#include
#include
#defineN120
shorta[N][N]={0};
shortn;
voidjijiehuanfang(shortn);
voidsuangoujiehuanfang(shortn);
voiddanoujiehuanfang(shortn);
intmain()
{
shortj,i;
printf("inputonenumberthatyoulike:
");
scanf("%d",&n);
if(n<3)
{
printf("thenumberiserror\n");
exit(-1);
}
if(n%2==1)//判断是否是奇阶幻方
jijiehuanfang(n);
else
if(n%4==0)//判断是否为双偶阶幻方
suangoujiehuanfang(n);
else//判断是否为单偶阶幻方
danoujiehuanfang(n);
for(j=0;j{
for(i=0;iprintf("%3d",a[j][i]);
printf("\n");
}
return1;
}
voidjijiehuanfang(shortn)
{
shorti,j,k;
i=(n+1)/2-1;
j=0;
a[j][i]=1;
for(k=2;k<=n*n;k++)
{
if(j==0&&i!
=n-1)//判断是否在最上行不在最右行
{
j=n-1;
i++;
a[j][i]=k;
}
elseif(j!
=0&&i==n-1)//判断是否在最右行不在最上行
{
j--;
i=0;
a[j][i]=k;
}
elseif(j==0&&i==n-1)//判断是否在最上行最右行
{
i=0;
j=n-1;
if(a[j][i]==0)//判断最左下角是否已有数字
a[j][i]=k;
else
{
i=n-1;
j=1;
a[j][i]=k;//把值赋给它下面的数组
}
}
else
{
j--;
i++;
if(a[j][i]==0)//判断他左上角是否已有数字
a[j][i]=k;
else
{
j+=2;
i--;
a[j][i]=k;//把值赋给它下面的数组
}
}
}
}
voidsuangoujiehuanfang(shortn)
{
shorti,j,k,ni,nj;
for(j=0,k=1;jfor(i=0;i{
a[j][i]=k;
k++;
}
for(j=0,k=1;jfor(i=0;i{
ni=i;
nj=j;
while(ni>3||nj>3)//把大区域转成小区域
{
if(ni>3)
ni-=4;
if(nj>3)
nj-=4;
}
if(ni==nj||ni+nj==3)//判断是否在对角线上
a[j][i]=n*n+1-k;
k++;
}
}
voiddanoujiehuanfang(shortn)
{
voiddanoujiehuanfangA(shortm);
voiddanoujiehuanfangB(shortm);
voiddanoujiehuanfangC(shortm);
voiddanoujiehuanfangD(shortm);
shorti,j,m,temp;
m=(n-2)/4;
danoujiehuanfangA(m);
danoujiehuanfangB(m);
danoujiehuanfangC(m);
danoujiehuanfangD(m);
for(j=0;j<(n+1)/2;j++)
for(i=0;i{
if(j!
=(2*m+1+1)/2-1)
if(i{
temp=a[j][i];
a[j][i]=a[j+2*m+1][i];
a[j+2*m+1][i]=temp;
}
else;
else
if(i>=m&&i<=m+m-1)
{
temp=a[j][i];
a[j][i]=a[j+2*m+1][i];
a[j+2*m+1][i]=temp;
}
}
for(j=0;j<(n+1)/2;j++)
for(i=0;iif(i>=3*m+1&&i<=4*m-1)
{
temp=a[j][i];
a[j][i]=a[j+2*m+1][i];
a[j+2*m+1][i]=temp;
}
}
voiddanoujiehuanfangA(shortm)
{
shorti,j,k,n;//注意单偶阶幻方A的n不是全局变量的n;方法和奇阶幻方的方法相同
n=2*m+1;
i=(n+1)/2-1;
j=0;
a[j][i]=1;
for(k=2;k<=n*n;k++)
{
if(j==0&&i!
=n-1)
{
j=n-1;
i++;
a[j][i]=k;
}
elseif(j!
=0&&i==n-1)
{
j--;
i=0;
a[j][i]=k;
}
elseif(j==0&&i==n-1)
{
i=0;
j=n-1;
if(a[j][i]==0)
a[j][i]=k;
else
{
i=n-1;
j=1;
a[j][i]=k;
}
}
else
{
j--;
i++;
if(a[j][i]==0)
a[j][i]=k;
else
{
j+=2;
i--;
a[j][i]=k;
}
}
}
}
voiddanoujiehuanfangB(shortm)//单偶阶幻方B的方法和奇阶幻方的方法相同
{
shorti,j,k;
i=3*m+1;
j=0;
a[j][i]=2*(2*m+1)*(2*m+1)+1;
for(k=2*(2*m+1)*(2*m+1)+2;k<=3*(2*m+1)*(2*m+1);k++)
{
if(j==0&&i!
=n-1)
{
j=2*m;
i++;
a[j][i]=k;
}
elseif(j!
=0&&i==n-1)
{
j--;
i=2*m+1;
a[j][i]=k;
}
elseif(j==0&&i==n-1)
{
j=2*m;
i=2*m+1;
if(a[j][i]==0)
a[j][i]=k;
else
{
j=1;
i=n-1;
a[j][i]=k;
}
}
else
{
j--;
i++;
if(a[j][i]==0)
a[j][i]=k;
else
{
j+=2;
i--;
a[j][i]=k;
}
}
}
}
voiddanoujiehuanfangC(shortm)//单偶阶幻方C的方法和奇阶的方法相同
{
shorti,j,k;
i=m;
j=2*m+1;
a[j][i]=3*(2*m+1)*(2*m+1)+1;
for(k=3*(2*m+1)*(2*m+1)+2;k<=4*(2*m+1)*(2*m+1);k++)
{
if(j==2*m+1&&i!
=2*m)
{
j=n-1;
i++;
a[j][i]=k;
}
elseif(j!
=2*m+1&&i==2*m)
{
i=0;
j--;
a[j][i]=k;
}
elseif(j==2*m+1&&i==2*m)
{
j=n-1;
i=0;
if(a[j][i]==0)
a[j][i]=k;
else
{
j=2*m+2;
i=2*m;
a[j][i]=k;
}
}
else
{
j--;
i++;
if(a[j][i]==0)
a[j][i]=k;
else
{
j+=2;
i--;
a[j][i]=k;
}
}
}
}
voiddanoujiehuanfangD(shortm)//单偶阶幻方D的方法和奇阶幻方的方法相同
{
shorti,j,k;
i=3*m+1;
j=2*m+1;
a[j][i]=(2*m+1)*(2*m+1)+1;
for(k=(2*m+1)*(2*m+1)+2;k<=2*(2*m+1)*(2*m+1);k++)
{
if(j==2*m+1&&i!
=n-1)
{
j=n-1;
i++;
a[j][i]=k;
}
elseif(j!
=2*m+1&&i==n-1)
{
j--;
i=2*m+1;
a[j][i]=k;
}
elseif(j==2*m+1&&i==n-1)
{
j=n-1;
i=2*m+1;
if(a[j][i]==0)
a[j][i]=0;
else
{
j=2*m+2;
i=n-1;
a[j][i]=k;
}
}
else
{
j--;
i++;
if(a[j][i]==0)
a[j][i]=k;
else
{
j+=2;
i--;
a[j][i]=k;
}
}
}
}