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

c语言程序设计--奇数阶幻方的生成利用二维数组,第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");

}

#include<stdioh>

void main()

{

int i,j,k;

int a[4][4];

for(i = 0,k = 1; i < 4; i++)

for(int j = 0; j < 4; j++)

{

if((i == j) || (i + j == 3))

a[i][j] = 17 - k;

else

a[i][j] = k;

k++;

}

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

{

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

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

printf("\n");

}

}

你最好去看一下幻方的规律!

#include<stdioh>

void main()

{

int i,j,k,m,n;

int a[20][20];

printf("please input the m:");//输入魔方阵阶数

scanf("%d",&m);

for(n=3;n<=m;n++)

{

if(n%2!=0)

{

 printf("%4d阶魔方阵如下:\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;

 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");

 for(i=0;i<n;i++)  //打印魔方阵

 {

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

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

  printf("\n\n");

 }

}

}

}

4阶的话,可以考虑直接递归搜索。我试了试有2992组解。

1 2 11 12

4 9 8 5

7 10 3 14

6 13 16 15

1 2 11 12

4 9 8 5

13 10 3 14

6 7 16 15

1 2 11 12

4 15 8 5

7 16 3 14

6 13 10 9

1 2 11 12

4 15 8 5

13 16 3 14

6 7 10 9

1 2 11 12

10 3 8 5

7 16 15 14

6 13 4 9

1 2 11 12

10 3 8 5

13 16 15 14

6 7 4 9

1 2 11 12

10 9 8 5

7 4 3 14

6 13 16 15

1 2 11 12

10 9 8 5

7 4 15 14

6 13 16 3

1 2 11 12

10 9 8 5

13 4 3 14

6 7 16 15

1 2 11 12

10 9 8 5

13 4 15 14

6 7 16 3

…………

#include <stdioh>

#include <mathh>

#include <windowsh>

#define MAX_NUM 30

#define _PRINT_ 0

unsigned long Result[MAX_NUM MAX_NUM], ResultNum, Used[MAX_NUM MAX_NUM]={0};

bool PrimeTable[MAX_NUM MAX_NUM 2]={ false };

unsigned long N, QN;

void CreatePrimeTable(void)

{

PrimeTable[0]=false;

PrimeTable[1]=false;

PrimeTable[2]=true;

PrimeTable[3]=true;

for(unsigned long j=5; j <= MAX_NUM MAX_NUM 2; j+=2)

{

PrimeTable[j]=true;

for(unsigned long i=3; i <= sqrt((double)j); i+=2)

{

if(j % i == 0)

{

PrimeTable[j]=false;

break;

}

}

}

}

inline bool IsPrime(unsigned long n)

{

return PrimeTable[n];

}

bool CheckIt(unsigned long Deep)

{

if(Deep == 0)

{

return true;

}

else if(Deep < N)

{

return IsPrime(Result[Deep] + Result[Deep - 1]);

}

else if(Deep % N == 0)

{

return IsPrime(Result[Deep] + Result[Deep - N]);

}

else

{

return(IsPrime(Result[Deep] + Result[Deep - 1]) && IsPrime(Result[Deep] + Result[Deep - N]));

}

}

void go(unsigned long Deep)

{

if(Deep == QN)

{

ResultNum++;

#if (_PRINT_)

printf("Find it! No%lu\n", ResultNum);

for(unsigned long i=0; i < QN; i++)

{

printf("%lu\t", Result[i]);

if(i % N == N - 1)

{

printf("\n");

}

}

#else

printf("\rFind:%lu", ResultNum);

#endif

}

else

{

for(unsigned long i=1; i <= QN; ++i)

{

if(!Used[i])

{

Result[Deep]=i;

if(CheckIt(Deep))

{

Used[i]=1;

go(Deep + 1);

Used[i]=0;

}

}

}

}

}

int main()

{

DWORD tim;

ResultNum=0;

printf("Input N:");

scanf("%lu", &N);

QN=N N;

tim=GetTickCount();

CreatePrimeTable();

go(0);

printf("\n\nN=%lu\n", N);

printf("Total=%lu\n", ResultNum);

printf("Time=%lu\n", GetTickCount() - tim);

return 0;

}

关于补充问题:

相邻 不包含斜方向的吧?相邻不就是上下、左右……包含斜线的话,再增加一种情况就可以了。不过用的时间会多点

这个打印n阶的 0<n<=15是奇数 我在下面帮你改了个3阶的

/ bookp33c 打印魔方阵程序 /

/ 谭浩强,C程序设计题解与上机指导,33页 /

/ 在tc30下编译通过 /

/ 20011212 /

void main()

{

int a[16][16],i,j,k,p,m,n;

p=1;

while(p==1)

{ printf("请输入n(0<n<=15,n是奇数)\n");

scanf("%d",&n);

if((n>=0)&&(n<=15)&&(n%2!=0))

{ printf("矩阵阶数是:%d\n",n);

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<=nn;k++)

{ i=i-1;

j=j+1;

if((i<1)&&(j>n))

{ i=i+2;

j=j-1;

}

else

{if(i<1) i=n; if(j>n) 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(" %3d",a[i][j]);

printf("\n");

}

}

3阶的

int main()

{

int a[16][16],i,j,k,n;

n=3;

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<=nn;k++)

{ i=i-1;

j=j+1;

if((i<1)&&(j>n))

{ i=i+2;

j=j-1;

}

else

{if(i<1) i=n; if(j>n) 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(" %3d",a[i][j]);

printf("\n");

}

return (1);

}

#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≥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

以上就是关于c语言程序设计--奇数阶幻方的生成 利用二维数组全部的内容,包括:c语言程序设计--奇数阶幻方的生成 利用二维数组、求C语言编写四阶幻方程序!用数组!、用C语言编写,1到九放到3*3的格子里,让3个的和都相等,等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存