没听说过这个东西
但是在编程爱好者找到了一个
你看看行不行
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个的和都相等,等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)