您的位置:

幻方奇数c语言,n阶奇数幻方C语言

本文目录一览:

C语言填幻方(不要穷举,要详细讲解)

下面的够详细了吧

奇阶幻方

当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为奇数的与幻方内以中心点为对称点的左下角对角数字进行交换。(保证不同时为奇或偶即可。)

方法二;将幻方等分成m*m个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阶幻方中间,再用本方法将边缘数字填写完毕。本方法适用于n4的所有幻方,我于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

魔鬼幻方

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

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

15 10 3 6

4 5 16 9

14 11 2 7

1 8 13 12

罗伯法:

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

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

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

怎样用C语言编写幻方

你的这个问题实际上包括两个问题:

1、幻方的算法

2、怎样用C语言实现幻方的算法

这两个问题是大不同的。

关于幻方的算法,或者叫幻方填法,目前有很多种,拉丁正交、马步法等等,针对奇数或者偶数(又分单偶数和双偶数)等有不同的算法,但这些算法只是帮你找到幻方的一个或多个实例(不会是全部),而同阶数的幻方到底有多少个,那只有用穷举法了,比如4阶幻方,基本4阶幻方共7040个,剔除旋转翻转的,即具有独立结构的共880个;4阶完美幻方共84个,具有独立结构的共48个。

对于高阶幻方(比如超过8阶),穷举法实际上是不可行的,因为它的穷举时间将是天文数字(以目前主流PC),所以不要试图用计算机穷举高阶幻方的全部结果,那将是徒劳的。

如果你只是需要1个实例,那么推荐你使用MATLAB语言工具,因为它提供了幻方函数magic(n),不需要编程,直接从命令窗口输入就可以得到答案。

至于第二个问题,当然你首先会C语言,剩下的就是编程技巧问题了,而这个问题是无从回答的。相信你问的是第一个问题。

以上的回答虽然没有明确给出答案,但相信对你会有帮助。

c语言程序设计——奇数阶幻方的生成 利用二维数组

#includestdio.h

void main()

{

int a[32][32],i,j,k,p,n;

p=1;

while(p==1)

{

printf("Enter n(n=1~25)");

scanf("%d",n);

if((n!=0)(n=25)(n%2!=0))

p=0;

}

for(i=1;i=n;i++)

for(j=1;j=n;j++)

a[i][j]=0;

j=n/2+1;

a[1][j]=1;

for(k=2;k=n*n;k++)

{

i=i-1;

j=j+1;

if((i1)(jn))

{

i=i+2;

j=j-1;

}

else

{

if(i1)

i=n;

if(jn)

j=1;

}

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

a[i][j]=k;

else

{

i=i+2;

j=j-1;

a[i][j]=k;

}

}

for(i=1;i=n;i++)

{

for(j=1;j=n;j++)

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

printf("\n");

}

}

做25*25以内的幻方

C++解决奇阶幻方问题的方法

幻方最早记载于我国公元前500年的春秋时期《大戴礼》中,这说明我国人民早在2500年前就已经知道了幻方的排列规律。而在国外,公元130年,希腊人塞翁才第一次提起幻方。我国不仅拥用幻方的发明权,而且是对幻方进行深入研究的国家。公元13世纪的数学家杨辉已经编制出3-10阶幻方,记载在他1275年写的《续古摘厅算法》一书中。在欧洲,直到574年,德国著名画家丢功才绘制出了完整的4阶幻方。

数学上已经证明,对于n2,n阶幻方都存在。目前填写幻方的方法,是把幻方分成了三类,每类又有各种各样的填写方法。

1、奇数阶幻方

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)。

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

2、双偶阶幻方

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

先说明一个定义。互补:如果两个数字的和,等于幻方最大数和最小数的和,即 n*n+1,称为互补。

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

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

这里,n×n+1 = 4×4+1 = 17;把1换成17-1 = 16;把6换成17-6 = 11;把11换成17-11 = 6……换完后就是一个四阶幻方。

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

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象限按奇数阶幻方的填法填数。

(2) 在A象限的中间行、中间格开始,按自左向右的方向,标出k格。A象限的其它行则标出最左边的k格。将这些格,和C象限相对位置上的数,互换位置。

(3) 在B象限任一行的中间格,自右向左,标出k-1列。(注:6阶幻方由于k-1=0,所以不用再作B、D象限的数据交换),将B象限标出的这些数,和D象限相对位置上的数进行交换,就形成幻方。

看起来很麻烦,其实掌握了方法就很简单了。

c语言程序设计--奇数阶幻方的生成 利用二维数组

没听说过这个东西

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

你看看行不行

main()

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

scanf("%d",n);

for(i=0;in;i++)

for(j=0;jn;j++)

a[i][j]=0;

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

for(k=2;k=n*n;k++)

{ i-=1;j+=1;

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

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

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

else a[i][j]=k;

}

for(i=0;in;i++)

{ for(j=0;jn;j++)

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

printf("\n");

}

printf("\n");

}

谁知道用C语言怎么写求幻方的程序?

#include stdio.h

#include stdlib.h

#include math.h

#include conio.h

#define MAX_INDEX 100

void swap(int *a,int *b)

{

int t;

t=*a;

*a=*b;

*b=t;

}

/*快速排序算法*/

void QuickSort(int a[], int l, int r)

{

int i=l; /*从左至右的游标*/

int j=r + 1; /*从右到左的游标*/

int pivot=a[l];

if (l = r) return;

/*把左侧= pivot的元素与右侧= pivot 的元素进行交换*/

while (1)

{

do

{/*在左侧寻找= pivot 的元素*/

i = i + 1;

} while (a[i] pivot);

do

{/*在右侧寻找= pivot 的元素*/

j = j - 1;

} while (a[j] pivot);

if (i = j) break; /*未发现交换对象*/

swap(a[i],a[j]);

}

/*设置p i v o t*/

a[l] = a[j];

a[j] = pivot;

QuickSort(a, l, j-1); /*对左段排序*/

QuickSort(a, j+1, r); /*对右段排序*/

}

void Huanf(int Array[][MAX_INDEX],int n)

{

int i,j;

int a,b,m;

int tempArray1[MAX_INDEX];

int tempArray2[MAX_INDEX];

a=n/2;

b=a+1;

m=n%4;

switch(m)

{

case 0:

case 2:

/*穿心对调*/

for(i=0;in;i++)

for(j=0;jn/2;j++)

{

if(in/2)

{

if(i%2==1Array[i][j]%2==0)/*偶行换偶*/

{

swap(Array[i][j],Array[n-1-i][n-1-j]);

}

else if(i%2==0Array[i][j]%2==1)/*奇行换奇*/

{

swap(Array[i][j],Array[n-1-i][n-1-j]);

}

}

else

{

if(i%2==1Array[i][j]%2==1)/*偶行换奇*/

{

swap(Array[i][j],Array[n-1-i][n-1-j]);

}

else if(i%2==0Array[i][j]%2==0)/*奇行换偶*/

{

swap(Array[i][j],Array[n-1-i][n-1-j]);

}

}

}

/*End穿心对调*/

if(m==2)

{

for(i=0;in/2;i++)

{

if((i!=0)(i!=a-1)(i!=b-1)(i!=n-1))

{

swap(Array[i][a-1],Array[n-1-i][a-1]);

swap(Array[b-1][i],Array[b-1][n-1-i]);

}

}

swap(Array[0][a-1],Array[0][b-1]);

swap(Array[a-1][0],Array[b-1][0]);

swap(Array[2][0],Array[2][n-1]);

swap(Array[0][2],Array[n-1][2]);

}

break;

case 1:

case 3:

/*穿心对调*/

for(i=0;in;i++)

for(j=0;jn/2;j++)

{

if(in/2)

{

if(i%2==1Array[i][j]%2==0) /*偶行换偶*/

{

swap(Array[i][j],Array[n-1-i][n-1-j]);

}

else if(i%2==0Array[i][j]%2==0)/*奇行换奇*/

{

swap(Array[i][j],Array[n-1-i][n-1-j]);

}

}

else if(in/2)

{

if(i%2==1Array[i][j]%2==0)/*偶行换偶*/

{

swap(Array[i][j],Array[n-1-i][n-1-j]);

}

else if(i%2==0Array[i][j]%2==0)/*奇行换奇*/

{

swap(Array[i][j],Array[n-1-i][n-1-j]);

}

}

}

/*End穿心对调*/

/*重排米字*/

for(i=0;in;i++)

{

tempArray1[i]=Array[i][i];

tempArray2[i]=Array[a][i];

}

QuickSort(tempArray1,0,n-1);

QuickSort(tempArray2,0,n-1);

for(i=0;in;i++)

{

Array[i][i]=tempArray2[i];

Array[a][i]=tempArray1[i];

}

for(i=0;in;i++)

{

tempArray1[i]=Array[i][n-1-i];

tempArray2[i]=Array[i][a];

}

QuickSort(tempArray1,0,n-1);

QuickSort(tempArray2,0,n-1);

for(i=0;in;i++)

{

Array[i][n-1-i]=tempArray2[i];

Array[i][a]=tempArray1[i];

}

/*End重排米字*/

if(m==3)

{

for(i=0;in/2;i++)

{

if((i!=a-1)(i!=b-1)(i!=a+1))

{

swap(Array[i][a-1],Array[n-1-i][a-1]);

swap(Array[a-1][i],Array[a-1][n-1-i]);

}

}

swap(Array[a-1][a-1],Array[a+1][a+1]);

swap(Array[a-1][b-1],Array[a+1][b-1]);

}

break;

default:

break;

}

return;

}

void main()

{

int Ne[MAX_INDEX][MAX_INDEX];

int i,j,n;

while(1)

{

printf("Please Input N (0 quit): ");

scanf("%d",n);

if(n==0)

break;

/*数组赋初值*/

for(i=0;in;i++)

for(j=0;jn;j++)

Ne[i][j]=i*n+(j+1);

Huanf(Ne,n);

for(i=0;in;i++)

for(j=0;jn;j++)

{

printf("%-4d",Ne[i][j]);

if(j==n-1)

printf("\n\n");

}

printf("\n\n");

getch();

}

}