对于一个n为奇数的n*n纵横图(幻方)的C++程序

对于一个n为奇数的n*n纵横图(幻方)的C++程序,第1张

n阶幻方的填法(n≥3) 收藏

幻方,亦称纵横图。台湾称为魔术方阵。将自然数1,2,3,……nn排列成一个nn方阵,使得每行、每列以及两对角线上的各个数之和都相等,等于n/2(nn+1),这样的方阵称为幻方。

例如:把1,2,3,4,5,6,7,8,9填入33的格子,使得:每行、每列、两条对角线的和是15。

8 1 6

3 5 7

4 9 2

n是它的阶数,比如上面的幻方是3阶。n/2(nn+1)为幻方的变幻常数。数学上已经证明,对于n>2,n阶幻方都存在。

目前填写幻方的方法,是把幻方分成了三类,每类又有各种各样的填写方法。这里对于这三类幻方,仅举出一种方便手工填写的方法。

1、奇数阶幻方

n为奇数 (n=3,5,7,9,11……) (n=2k+1,k=1,2,3,4,5……)

奇数阶幻方最经典的填法是罗伯特法(也有人称之为楼梯方)。填写方法是这样:

把1(或最小的数)放在第一行正中; 按以下规律排列剩下的nn-1个数:

(1)、每一个数放在前一个数的右上一格;

(2)、如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;

(3)、如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;

(4)、如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在前一个数的下一行同一列的格内;

(5)、如果这个数所要放的格已经有数填入,处理方法同(4)。

这种写法总是先向“右上”的方向,象是在爬楼梯。

2、双偶阶幻方

n为偶数,且能被4整除 (n=4,8,12,16,20……) (n=4k,k=1,2,3,4,5……)

先说明一个定义:

互补:如果两个数字的和,等于幻方最大数和最小数的和,即 nn+1,称为互补。

先看看4阶幻方的填法:将数字从左到右、从上到下按顺序填写:

1 2 3 4

5 6 7 8

9 10 11 12

13 14 15 16

这个方阵的对角线,已经用蓝色标出。将对角线上的数字,换成与它互补的数字。

这里,nn+1 = 44+1 = 17;

把1换成17-1 = 16;把6换成17-6 = 11;把11换成17-11 = 6……换完后就是一个四阶幻方。

16 2 3 13

5 11 10 8

9 7 6 12

4 14 15 1

对于n=4k阶幻方,我们先把数字按顺序填写。写好后,按44把它划分成kk个方阵。因为n是4的倍数,一定能用44的小方阵分割。然后把每个小方阵的对角线,象制作4阶幻方的方法一样,对角线上的数字换成互补的数字,就构成幻方。 下面是8阶幻方的作法:

(1) 先把数字按顺序填。然后,按44把它分割成22个小方阵

1 2 3 4 5 6 7 8

9 10 11 12 13 14 15 16

17 18 19 20 21 22 23 24

25 26 27 28 29 30 31 32

33 34 35 36 37 38 39 40

41 42 43 44 45 46 47 48

49 50 51 52 53 54 55 56

57 58 59 60 61 62 63 64

(2) 每个小方阵对角线上的数字,换成和它互补的数。

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

3、单偶阶幻方

n为偶数,且不能被4整除 (n=6,10,14,18,22……) (n=4k+2,k=1,2,3,4,5……)

这是三种里面最复杂的幻方。

以n=10为例。这时,k=2

(1) 把方阵分为A,B,C,D四个象限,这样每一个象限肯定是奇数阶。用楼梯法,依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数。

A B

C D

17 24 1 8 15 67 74 51 58 65

23 5 7 14 16 73 55 57 64 66

4 6 13 20 22 54 56 63 70 72

10 12 19 21 3 60 62 69 71 53

11 18 25 2 9 61 68 75 52 59

92 99 76 83 90 42 49 26 33 40

98 80 82 89 91 48 30 32 39 41

79 81 88 95 97 29 31 38 45 47

85 87 94 96 78 35 37 44 46 28

86 93 100 77 84 36 43 50 27 34

(2) 在A象限的中间行、中间格开始,按自左向右的方向,标出k格。A象限的其它行则标出最左边的k格。

>>>

17 24 1 8 15 67 74 51 58 65

23 5 7 14 16 73 55 57 64 66

4 6 13 20 22 54 56 63 70 72

10 12 19 21 3 60 62 69 71 53

11 18 25 2 9 61 68 75 52 59

92 99 76 83 90 42 49 26 33 40

98 80 82 89 91 48 30 32 39 41

79 81 88 95 97 29 31 38 45 47

85 87 94 96 78 35 37 44 46 28

86 93 100 77 84 36 43 50 27 34

(3) 将这些格,和C象限相对位置上的数,互换位置。

92 99 1 8 15 67 74 51 58 65

98 80 7 14 16 73 55 57 64 66

4 6 88 95 22 54 56 63 70 72

85 87 19 21 3 60 62 69 71 53

86 93 25 2 9 61 68 75 52 59

17 24 76 83 90 42 49 26 33 40

23 5 82 89 91 48 30 32 39 41

79 81 13 20 97 29 31 38 45 47

10 12 94 96 78 35 37 44 46 28

11 18 100 77 84 36 43 50 27 34

(4) 在B象限任一行的中间格,自右向左,标出k-1列。(注:6阶幻方由于k-1=0所以不用再作B、D象限的数据交换)

<<<

92 99 1 8 15 67 74 51 58 65

98 80 7 14 16 73 55 57 64 66

4 6 88 95 22 54 56 63 70 72

85 87 19 21 3 60 62 69 71 53

86 93 25 2 9 61 68 75 52 59

17 24 76 83 90 42 49 26 33 40

23 5 82 89 91 48 30 32 39 41

79 81 13 20 97 29 31 38 45 47

10 12 94 96 78 35 37 44 46 28

11 18 100 77 84 36 43 50 27 34

(5) 将B象限标出的这些数,和D象限相对位置上的数进行交换,即可完成。

92 99 1 8 15 67 74 26 58 65

98 80 7 14 16 73 55 32 64 66

4 6 88 95 22 54 56 38 70 72

85 87 19 21 3 60 62 44 71 53

86 93 25 2 9 61 68 50 52 59

17 24 76 83 90 42 49 51 33 40

23 5 82 89 91 48 30 57 39 41

79 81 13 20 97 29 31 63 45 47

10 12 94 96 78 35 37 69 46 28

11 18 100 77 84 36 43 75 27 34

下面的够详细了吧

奇阶幻方

当n为奇数时,我们称幻方为奇阶幻方。可以用Merzirac法与loubere法实现,根据我的研究,发现用国际象棋之马步也可构造出更为神奇的奇幻方,故命名为horse法。

偶阶幻方

当n为偶数时,我们称幻方为偶阶幻方。当n可以被4整除时,我们称该偶阶幻方为双偶幻方;当n不可被4整除时,我们称该偶阶幻方为单偶幻方。可用了Hire法、 Strachey以及YinMagic将其实现,Strachey为单偶模型,我对双偶(4m阶)进行了重新修改,制作了另一个可行的数学模型,称之为 Spring。YinMagic是我于2002年设计的模型,他可以生成任意的偶阶幻方。

在填幻方前我们做如下约定:如填定数字超出幻方格范围,则把幻方看成是可以无限伸展的图形,如下图:

Merzirac法生成奇阶幻方

在第一行居中的方格内放1,依次向左上方填入2、3、4…,如果左上方已有数字,则向下移一格继续填写。如下图用Merziral法生成的5阶幻方:

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

loubere法生成奇阶幻方

在居中的方格向上一格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向上移二格继续填写。如下图用Louberel法生成的7阶幻方:

30 39 48 1 10 19 28

38 47 7 9 18 27 29

46 6 8 17 26 35 37

5 14 16 25 34 36 45

13 15 24 33 42 44 4

21 23 32 41 43 3 12

22 31 40 49 2 11 20

horse法生成奇阶幻方

先在任意一格内放入1。向左走1步,并下走2步放入2(称为马步),向左走1步,并下走2步放入3,依次类推放到n。在n的下方放入n+1(称为跳步),再按上述方法放置到2n,在2n的下边放入2n+1。如下图用Horse法生成的5阶幻方:

77 58 39 20 1 72 53 34 15

6 68 49 30 11 73 63 44 25

16 78 59 40 21 2 64 54 35

26 7 69 50 31 12 74 55 45

36 17 79 60 41 22 3 65 46

37 27 8 70 51 32 13 75 56

47 28 18 80 61 42 23 4 66

57 38 19 9 71 52 33 14 76

67 48 29 10 81 62 43 24 5

一般的,令矩阵[1,1]为向右走一步,向上走一步,[-1,0]为向左走一步。则马步可以表示为2X+Y,{X∈{[1,0], [-1,0]},Y∈{[0,1], [0,-1]}}∪{Y∈{[1,0], [-1,0]},X∈{[0,1], [0,-1]}}。对于2X+Y相应的跳步可以为2Y,-Y,X,-Y,X,3X,3X+3Y。上面的的是X型跳步。Horse法生成的幻方为魔鬼幻方。

Hire法生成偶阶幻方

将n阶幻方看作一个矩阵,记为A,其中的第i行j列方格内的数字记为a(i,j)。在A内两对角线上填写1、2、3、……、n,各行再填写1、2、3、……、n,使各行各列数字之和为n(n+1)/2。填写方法为:第1行从n到1填写,从第2行到第n/2行按从1到进行填写(第2行第1列填n,第2行第n列填1),从第n/2+1到第n行按n到1进行填写,对角线的方格内数字不变。如下所示为6 阶填写方法:

1 5 4 3 2 6

6 2 3 4 5 1

1 2 3 4 5 6

6 5 3 4 2 1

6 2 4 3 5 1

1 5 4 3 2 6

如下所示为8阶填写方法(转置以后):

1 8 1 1 8 8 8 1

7 2 2 2 7 7 2 7

6 3 3 3 6 3 6 6

5 4 4 4 4 5 5 5

4 5 5 5 5 4 4 4

3 6 6 6 3 6 3 3

2 7 7 7 2 2 7 2

8 1 8 8 1 1 1 8

将A上所有数字分别按如下算法计算,得到B,其中b(i,j)=n×(a(i,j)-1)。则AT+B为目标幻方

(AT为A的转置矩阵)。如下图用Hire法生成的8阶幻方:

1 63 6 5 60 59 58 8

56 10 11 12 53 54 15 49

41 18 19 20 45 22 47 48

33 26 27 28 29 38 39 40

32 39 38 36 37 27 26 25

24 47 43 45 20 46 18 17

16 50 54 53 12 11 55 9

57 7 62 61 4 3 2 64

Strachey法生成单偶幻方

将n阶单偶幻方表示为4m+2阶幻方。将其等分为四分,成为如下图所示A、B、C、D四个2m+1阶奇数幻方。

A C

D B

A用1至2m+1填写成(2m+1)2阶幻方;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+1至4(2m+1)2填写成 2m+1阶幻方;在A中间一行取m个小格,其中1格为该行居中1小格,另外m-1个小格任意,其他行左侧边缘取m列,将其与D相应方格内交换;B与C接近右侧m-1列相互交换。如下图用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

Spring法生成以偶幻方

将n阶双偶幻方表示为4m阶幻方。将n阶幻方看作一个矩阵,记为A,其中的第i行j列方格内的数字记为a(i,j)。

先令a(i,j)=(i-1)n+j,即第一行从左到可分别填写1、2、3、……、n;即第二行从左到可分别填写n+1、n+2、n+3、……、2n;…………之后进行对角交换。对角交换有两种方法:

方法一;将左上区域i+j为偶数的与幻方内以中心点为对称点的右下角对角数字进行交换;将右上区域i+j为奇数的与幻方内以中心点为对称点的左下角对角数字进行交换。(保证不同时为奇或偶即可。)

方法二;将幻方等分成mm个4阶幻方,将各4阶幻方中对角线上的方格内数字与n阶幻方内以中心点为对称点的对角数字进行交换。

如下图用Spring法生成的4阶幻方:

16 2 3 13

5 11 10 8

9 7 6 12

4 14 15 1

YinMagic构造偶阶幻方

先构造n-2幻方,之后将其中的数字全部加上2n-2,放于n阶幻方中间,再用本方法将边缘数字填写完毕。本方法适用于n>4的所有幻方,我于2002年12月31日构造的数学模型。YinMagic法可生成6阶以上的偶幻方。如下图用 YinMagic法生成的6阶幻方:

10 1 34 33 5 28

29 23 22 11 18 8

30 12 17 24 21 7

2 26 19 14 15 35

31 13 16 25 20 6

9 36 3 4 32 27

魔鬼幻方

如将幻方看成是无限伸展的图形,则任何一个相邻的nn方格内的数字都可以组成一个幻方。则称该幻方为魔鬼幻方。

用我研究的Horse法构造的幻方是魔鬼幻方。如下的幻方更是魔鬼幻方,因为对于任意四个在两行两列上的数字,他们的和都是34。此幻方可用YinMagic方法生成。

15 10 3 6

4 5 16 9

14 11 2 7

1 8 13 12

罗伯法:

1居上行正中央,依次排开右上方。

右出格时写最左,上出格时写最下

每逢几个落一行(几个是几几的方阵中的几)

没听说过这个东西

但是在编程爱好者找到了一个

你看看行不行

main()

{ int i,j,n,k=1,a[N][N];

scanf("%d",&n);

for(i=0;i<n;i++)

for(j=0;j<n;j++)

a[i][j]=0;

a[i=0][j=n/2]=k;

for(k=2;k<=nn;k++)

{ i-=1;j+=1;

if(i==-1&&j!=n) {i=n-1;a[i][j]=k;}

else if(j==n&&i!=-1) {j=0;a[i][j]=k;}

else if((i==-1&&j==n)||a[i][j]!=0) {i+=2;j-=1;a[i][j]=k;}

else a[i][j]=k;

}

for(i=0;i<n;i++)

{ for(j=0;j<n;j++)

printf("%3d",a[i][j]);

printf("\n");

}

printf("\n");

}

你没给代码 我不知道你错误在哪里

说说变长数组吧

c标准是不支持变长数组的 但是个别的编译器支持 比如gcc 不支持的时候 如你所说 编译报错

有几个解决方案

1 定义一个够大的数组 缺点是浪费空间

2 实用malloc动态申请 输入时首先输入数组大小 然后实用malloc申请相应大小的空间 缺点是输入数据多

我觉得应该是你代码有错 可能是你对数组的定义理解有错 最好把代码贴上来

#include<stdioh>

int main()

{

int i,j,i1,j1,x,a[100][100];

for(i=1;i<=3;i++)

{

for(j=1;j<=3;j++)

a[i][j] = 0;

}

i=1;

j = (int)((3+1)/2);

x=1;

while(x<=33)

{

a[i][j] = x;

x++;

i1=i;

j1=j;

i--;

j--;

if(i==0)

i=3;

if(j==0)

j=3;

if(a[i][j] != 0)

{

i = i1+1;

j = j1;

}

}

for(i=1;i<=3;i++)

{

for(j=1;j<=3;j++)

printf("%3d",a[i][j]);

printf("\n");

}

return 1;

}

因为你是通过用户输入的方式确定幻方的阶数,而定义二维数组的维数必须是一个常数,不能是n这个变量,要么你就在程序中规定二维数组的大小,这个可以用宏定义规定n大小,#define n x,x是一个确定的常数

第二种方法是将数组变成二维动态数组如下所示

int p;

p=new int[n];

for(int i=0;i<n;i++){

p[i]=new int[n];

}

我是用手机打的字,格式不是很标准,具体你可以百度一个二维动态数组,这个知识点应该是在你们后面才会学,现在应该还没学

你先看看吧:

3阶幻方:

8 1 6

3 5 7

4 9 2

5阶幻方:

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

#include <stdioh>

#define N 5

void main()

{

int i,j,k,a[N][N];

for(i=0;i<N;i++)

for(j=0;j<N;j++)

a[i][j]=0; /初始值为零/

j=N/2;

a[0][j]=1; /确定1的位置/

for(k=2;k<=NN;k++)

{

i--;

j++;

if(i<0)

i=N-1; /行出界/

else if(j>N-1)

j=0; /列出界/

if(a[i][j]==0)

a[i][j]=k; /按规律顺序确定数值位置/

else

{

i=(i+2)%N;

j=(j-1+N)%N;

a[i][j]=k; /已有数字时数字的位置/

}

}

printf("\n\n");

for(i=0;i<N;i++)

{

printf("\t");

for(j=0;j<N;j++)

printf("%4d",a[i][j]); /显示幻方阵/

printf("\n\n");

}

return;

}

最好是自己研究下 ,印象比较深刻。

好好学习呀 其实我也只是个初学者

以上就是关于对于一个n为奇数的n*n纵横图(幻方)的C++程序全部的内容,包括:对于一个n为奇数的n*n纵横图(幻方)的C++程序、C语言填幻方(不要穷举,要详细讲解)、c语言程序设计--奇数阶幻方的生成 利用二维数组等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/10626299.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-10
下一篇 2023-05-10

发表评论

登录后才能评论

评论列表(0条)

保存