当前位置:首页 » 编程语言 » 求解四阶幻方的C语言
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

求解四阶幻方的C语言

发布时间: 2023-05-28 02:35:42

Ⅰ 如何用c语言编写幻方多谢回答

//分析:魔方阵有如下规律:
// 1:自然数1总是在方阵第一行当中一列上。
// 2:后续的自然数在当前数的右上方,
// 1)如果是在第一行则行数变为第n行列数加1 ;
// 2)如果是在最后一列,行数减1,列数为第1行。
// 3)如果后续的数所处位置已有数,则行数加1,列数不变。
/******************************************************************************************************************************
巧填奇数阶幻方(魔方阵)[转]2007-01-03 17:57 一、什么叫幻方?
(通俗点说)把一些有规律的数填在纵横格数都相等的正方形图内,使每一行、每一列和每一条对角线上各个数之和都相等。这样的方阵图叫做幻方。
幻方又分为奇数阶幻方和偶数阶幻方。奇数阶幻方是指横行、竖列都是单数(即3、5、7、9……)的方阵图。偶数阶幻方是指横行、竖列都是双数(即4、6、8、10……)的方阵图。
二、奇数阶幻方的填法。
奇数阶幻方中最简便的一种就是三阶幻方,又称“九宫图”。
平常我们遇到这类题都是用分析、分组、尝试的方法推出,这种方法较麻烦,如果是五阶幻方、七阶幻方就更困难了。
有一种方法不仅能很快地填出三阶幻方,还能很快地填出五阶幻方、七阶幻方、九阶幻方……那就是“口诀法”
口 诀
“1”坐边中间,斜着把数填;
出边填对面,遇数往下旋;
出角仅一次,转回下格间。
注意:
(1)这里的“1”,是指要填的这一列数中的第一个数。
(2)“1”坐边中间,指第一个数要填在任何一边的正中间的空格里。
(3)从1到2时,必须先向边外斜(比如:第一个数填在上边的正中间,填第二个数时,要向左上方或右上方斜),填后面的数时也要按照同样的方向斜。
*******************************************************************************************************************************/
#include<iostream>
using namespace std;
void main()
{
int a[32][32],i,j,k,p,n;
p=1;
while(p==1)
{
cout<<"Enter n(n=1~25):";
cin>>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((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++)
cout<<a[i][j]<<" ";
cout<<endl;
}

}

/*C_ban*
所谓的魔方距阵就是一种特殊的奇数阶方阵:它的行,列,对角线,上的数字之和都要相等,且方阵中的每一个数字都不相等,且数字的范围都在1到n*n之间.
我编的程序如下:
*/
#include<stdio.h>
#define N 15
main()
{
int i,j,row,cloum,size,square[N][N],count;
clrscr();
printf("please enter the square size(odd && <=15):\n");
scanf("%d",&size);
while(size%2==0||size>15||size<3)
{
printf("error e to the wrng input!please input it again!\n");
scanf("%d",&size);
}
for(i=0;i<size;i++)
for(j=0;j<size;j++)
square[i][j]=0;
i=0;j=(size-1)/2;
square[i][j]=1;
for(count=2;count<=size*size;count++)
{
row=i-1<0?(size-1):(i-1);
cloum=j-1<0?(size-1):(j-1);
if(square[row][cloum])
i=(++i)%size;
else
{i=row;
j=j-1<0?(size-1):(j-1);
}
square[i][j]=count;
}
printf("the %d square is:\n",size);
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
printf("%d",square[i][j]);
printf("\n");
}
}

只能求奇数的魔方阵
#define N 20
main()
{
int a[N][N];
int n,i,j,r;
scanf("%d",&n);
for(i=0;i<N;i++) for(j=0;j<N;j++) a[i][j]=0;
i=0;
j=n/2;
a[i][j]=1;
for (r=2;r<=n*n;r++)
if (a[(i+n-1)%n][(j+1)%n]==0)
{i=(i+n-1)%n;j=(j+1)%n;a[i][j]=r;}
else
{i=(i+1)%n;a[i][j]=r;}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++) printf("%4d",a[i][j]);
printf("\n");
}
}
这是以前别人写的,你参考一下!

Ⅱ 高手们,帮忙啊,c语言程序设计

*问题分析与算法设计
最简单的算法是:采用穷举法,设定4X4矩阵中每一个元素的值后,判断每一行、每一列和两条对角线上的4个数字组成的四位数是否都是可逆素数,若是则求出了满足题意的一个解。
这种算法在原理是对的,也一定可以求出满足题意的全部解。但是,按照这一思路编出的程序效率很低,在微机上几个小时也不会运行结束。这一算法致命的缺陷是:要穷举和判断的情况过多。
充分利用题目中的“每一个四位数都是可逆素数”这一条件,可以放弃对矩阵中每个元素进行的穷举的算法,先求出全部的四位可逆素数(204个),以矩阵的行为单位,在四位可逆素数的范围内进行穷举,然后将穷举的四位整数分解为数字后,再进行列和对角线方向的条件判断,改进的算法与最初的算法相比,大大地减少了穷举的次数。
考虑矩阵的第一行和最后一行数字,它们分别是列方向四位数的第一个数字和最后一个数字,由于这些四位数也必须是可逆素数,所以矩阵的每一行和最后一行中的各个数字都不能为偶数或5。这样穷举矩阵的第一行和最后一行时,它们的取值范围是:所有位的数字均不是偶数或5的四位可逆数。由于符合这一条件的四位可逆素数很少,所以这一范围限制又一次减少了穷举的次数。
对算法的进一步研究会发现:当设定了第一和第二行的值后,就已经可以判断出当前的这种组合是否一定是错误的(尚不能肯定该组合一定是正确的)。若按列方向上的四个两位数与四位可逆数的前两位矛盾(不是其中的一种组合),则第一、二行的取值一定是错误的。同理在设定了前三行数据后,可以立刻判断出当前的这种组合是否一定是错误的,若判断出矛盾情况,则可以立刻设置新的一组数据。这样就可以避免将四个数据全部设定好以后再进行判断所造成的低效。
根据以上分析,可以用伪语言描述以上改进的算法:
开始
找出全部四位的可逆素数;
确定全部出现在第一和最后一行的四位可逆素数;
在指定范围 内穷举第一行
在指定范围内穷举第二行
若第一、第二、三行已出现矛盾,则继续穷举下一个数;
在指定范围内穷举第四行
判断列和对角方向是否符合题意
若符合题意,则输出矩阵;
否则继续穷举下一个数;
结束
在实际编程中,采用了很多程序设计技巧,假如设置若干辅助数组,其目的就是要最大限度的提高程序的执行效率,缩短运行时间。下面的程序运行效率是比较高的。

*程序说明与注释
#include<stdio.h>
#include<math.h>
int number[210][5]; /*存放可逆素数及素数分解后的各位数字*/
int select[110]; /*可以放在矩阵第一行和最后一行的素数的下标*/
int array[4][5]; /*4X4的矩阵,每行0号元素存可逆素数对应的数组下标*/
int count; /*可逆素数的数目*/
int selecount; /*可以放在矩阵第一行和最后一行的可逆素数的数目*/
int larray[2][200]; /*存放素数前二、三位数的临时数组所对应的数量计数器*/
int lcount[2];
int num(int number);
int ok(int number);
void process(int i);
void _num(int i);
int comp_num(int n);
int find1(int i);
int find2(void);
int find0(int num);
void p_array(void);

int main()
{
int i,k,flag,cc=0,i1,i4;
printf("there are magic squares with invertable primes as follw:\n");
for(i=1001;i<9999;i+=2) /*求满足条件的可逆素数*/
{
k=i/1000;
if(k%2!=0&&k!=5&&num(i)) /*若可逆素数的第一位不是偶数或5*/
{
number[count][0]=i; /*存入数组*/
process(count++); /*分解素数的各位数字*/
if(number[count-1][2]%2!=0&& /*若可逆素数满足放在矩阵第一行*/
number[count-1][3]%2!=0&& /*和最后一行的条件,记录可逆素数的*/
number[count-1][2]!=5&& /*下标,计数器加1*/
number[count-1][3]!=5)
select[selecount++]=count-1;
}
}
larray[0][lcount[0]++]=number[0][0]/100; /*临时数组的第一行存前二位*/
larray[1][lcount[1]++]=number[0][0]/10; /*临时数组的第二行存前三位*/
for(i=1;i<count;i++) /*将素数不重复的前二、三位存入临时数组中*/
{
if(larray[0][lcount[0]-1]!=number[i][0]/100)
larray[0][lcount[0]++]=number[i][0]/100;
if(larray[1][lcount[1]-1]!=number[i][0]/10)
larray[1][lcount[1]++]=number[i][0]/10;
}
for(i1=0;i1<selecount;i1++) /*在第一行允许的汇聚围内穷举*/
{
array[0][0]=select[i1]; /*取对应的素数下标*/
_num(0); /*复制分解的素数*/
for(array[1][0]=0;array[1][0]<count;array[1][0]++) /*穷举第二行*/
{
_num(1); /*复制分解的数字*/
if(!comp_num(2))
continue; /*若每列的前两位的组成与素数相矛盾,则试探下一个数*/
for(array[2][0]=0;array[2][0]<count;array[2][0]++) /*穷举第三行*/
{
_num(2); /*复制分解的数字*/
if(!comp_num(3))
continue; /*若每列的前三位的组成与素数相矛盾,则试探下一个数*/
for(i4=0;i4<selecount;i4++) /*在最后一行允许的范围内穷举*/
{
array[3][0]=select[i4];
_num(3); /*复制分解的数字*/
for(flag=1,i=1;flag&&i<=4;i++) /*判断每列是否可逆素数*/
if(!find1(i))flag=0;
if(flag&&find2()) /*判断对角线是否为可逆素数*/
{ printf("No.%d\n",++cc); p_array(); } /*输出幻方矩阵*/
}
}
}
}
}

int num(int number) /*判断是否可逆素数*/
{
int j;
if(!ok(number)) return 0;
for(j=0;number>0;number/=10) /*将素数变为反序数*/
j=j*10+number%10;
if(!ok(j)) return 0; /*判断反序数是否为素数*/
return 1;
}

int ok(int number) /*判断是否为素数*/
{
int i,j;
if(number%2==0) return 0;
j=sqrt((double)number)+1;
for(i=3;i<=j;i+=2)
if(number%i==0) return 0;
return 1;
}

void process(int i) /*将第i个整数分解为数字并存入数组*/
{
int j,num;
num=number[i][0];
for(j=4;j>=1;j--,num/=10)
number[i][j]=num%10;
}

void _num(int i) /*将array[i][0]指向的素数的各位数字复制到array[i]中*/
{
int j;
for(j=1;j<=4;j++)
array[i][j]=number[array[i][0]][j];
}

int comp_num(int n) /*判断array中每列的前n位是否与可逆素数允许的前n位矛盾*/
{
static int ii; /*用内部静态变量保存前一次查找到的元素下标*/
static int jj; /*ii:前一次查找前二位的下标,jj:前一次查找前三位的下标*/
int i,num,k,*p; /*p:指向对应的要使用的前一次下标ii或jj*/
int *pcount; /*pcount:指向要使用的临时数组数量的计数器*/
switch(n){ /*根据n的值选择对应的一组控制变量*/
case 2:pcount=&lcount[0];p=ⅈbreak;
case 3:pcount=&lcount[1];p=&jj;break;
default:return 0;
}
for(i=1;i<=4;i++) /*对四列分别进行处理*/
{
for(num=0,k=0;k<n;k++) /*计算前n位数字代表的数值*/
num=num*10+array[k][i];
if(num<=larray[n-2][*p]) /*与前一次最后查找到的元素进行比较*/
for(;*p>=0&&num<larray[n-2][*p];(*p)--);/*若前次查找到的元素大,则向前找*/
else
for(;p<pcount&&num>larray[n-2][*p];(*p)++); /*否则向后找*/
if(*p<0||*p>=*pcount)
{
*p=0; return 0;
}
if(num!=larray[n-2][*p])
return 0; /*前n位不是可逆素数允许的值则返回0*/
}
return 1;
}

int find1(int i) /*判断列方向是否是可逆素数*/
{
int num,j;
for(num=0,j=0;j<4;j++)
num=num*10+array[j][i];
return find0(num);
}

int find2(void) /*判断对角线方向是否是可逆素数*/
{
int num1,num2,i,j;
for(num1=0,j=0;j<4;j++)
num1=num1*10+array[j][j+1];
for(num2=0,j=0,i=4;j<4;j++,i--)
num2=num2*10+array[j][i];
if(find0(num1)) return(find0(num2));
else return 0;
}

int find0(int num) /*查找是否为满足要求的可逆素数*/
{
static int j;
if(num<=number[j][0])for(;j>=0&&num<number[j][0];j--);
else for(;j<count&&num>number[j][0];j++);
if(j<0||j>=count){ j=0;return 0; }
if(num==number[j][0]) return 1;
else return 0;
}

void p_array(void) /*输出矩阵*/
{
int i,j;
for(i=0;i<4;i++)
{
for(j=1;j<=4;j++) printf("%d ",array[i][j]);
printf("\n");
}
}

*问题的进一步讨论
程序中大量技巧是用于尽早发现矛盾,减少循环次数,缩短运行时间。从实际效果看是相当不错的。但目前的程序仍然可以进一步优化。
当第四行设定了前三行后,尚未设定的行就没必要再使用穷举的方法,因为列方向设定好的三位数字已经限制了最后一个数字可能的取值,在可逆数中找出前三位数字与设定好的三位数字相同的素数。这些素数就是在这一列前面已设定好的三位数字的限制条件下可能的取值。此时每一列上只有不超过四个可能的取值。找出全部各列可能的取值(可能的四位可逆素数),求出它们的交集。若交集为空,即没有共同的可能取值,则列间数据相互矛盾否满足则将交集中的数据填 入矩阵中就是题目的一个解。
算法可再进一步优化。先穷举一、二和四列的数据,然后用上面的算法来确定第三行的值,这样可进一步缩小穷举的范围,提高运行效率。
分析输出的结果。可以看出本题的基本解只有17种,每个解可通过旋转与反射获得同构的其它7个解,可以进一步改进程序,只输出17个基本解。

Ⅲ 谁知道用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;i<n;i++)
for(j=0;j<n/2;j++)
{
if(i<n/2)
{
if(i%2==1&&Array[i][j]%2==0)/*偶行换偶*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
else if(i%2==0&&Array[i][j]%2==1)/*奇行换奇*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
}
else
{
if(i%2==1&&Array[i][j]%2==1)/*偶行换奇*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
else if(i%2==0&&Array[i][j]%2==0)/*奇行换偶*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
}

}
/*End穿心对调*/
if(m==2)
{
for(i=0;i<n/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;i<n;i++)
for(j=0;j<n/2;j++)
{
if(i<n/2)
{
if(i%2==1&&Array[i][j]%2==0) /*偶行换偶*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
else if(i%2==0&&Array[i][j]%2==0)/*奇行换奇*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
}
else if(i>n/2)
{
if(i%2==1&&Array[i][j]%2==0)/*偶行换偶*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
else if(i%2==0&&Array[i][j]%2==0)/*奇行换奇*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
}
}
/*End穿心对调*/
/*重排米字*/
for(i=0;i<n;i++)
{
tempArray1[i]=Array[i][i];
tempArray2[i]=Array[a][i];
}

QuickSort(tempArray1,0,n-1);
QuickSort(tempArray2,0,n-1);
for(i=0;i<n;i++)
{
Array[i][i]=tempArray2[i];
Array[a][i]=tempArray1[i];
}
for(i=0;i<n;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;i<n;i++)
{
Array[i][n-1-i]=tempArray2[i];
Array[i][a]=tempArray1[i];
}
/*End重排米字*/

if(m==3)
{
for(i=0;i<n/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;i<n;i++)
for(j=0;j<n;j++)
Ne[i][j]=i*n+(j+1);

Huanf(Ne,n);

for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
printf("%-4d",Ne[i][j]);
if(j==n-1)
printf("\n\n");
}
printf("\n\n");
getch();
}
}

Ⅳ 求素数幻方,这道题怎么做啊(c语言)

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 <stdio.h>
#include <math.h>
#include <windows.h>

#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;
}

关于补充问题:

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

Ⅳ 魔方阵的C语言

代码一:
#include <stdio.h>
#define N 16 //这里可以修改N的值,并且N只能为偶数
int main()
{
int a[N][N]={0},i,j,k,p,m,n;
p=1;
while(p==1)
{
printf(Enter n(1~%d): ,N-1);/*可以输入小于等于N-1的奇数*/
scanf(%d,&n);
if((n!=0)&&(n<N)&&(n%2!=0)) p=0;
}
i=n+1;
j=n/2+1; /*建立魔方阵*/
a[1][j]=1;
for(k=2;k<=n*n;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(%4d,a[i][j]);
printf( );
}
}
代码二:(相对于代码一条理更清晰,更简单、更容易理解)
将1~n的平方这几个数构成一个n阶魔方阵。
算法:
依以下法则,你可以很快的写出奇数阶幻方!当然,这种写法只是其中一个答案,而不是唯一答案。
1)将1填入第一行中间;
2)将每个数填在前一个数的右上方。
3)若该位置超出最上行,则改填在最下行的对应位置;
4)若该位置超出最右列,则该填在最左列的对应行位置;
5)若某元素填在第一行最右列,下一个数填在该数同列的下一行;
6)若某数已填好,但其右上角已填了其他数据,则下一个数填在该数同列的下一行位置。
#include<stdio.h>
void main()
{
int a[15][15]={0},i,j,m,n,temp,M;
printf(请输入一个3~15的奇数: );
scanf(%d,&M);
i=0;
j=M/2;
a[i][j]=1;
for(temp=2;temp<=M*M;temp++)
{
m=i;
n=j;
i--;
j++;
if(i<0)
i=M-1;
if(j>M-1)
j=0;
if(a[i][j]!=0)
{
i=m+1,j=n;
a[i][j]=temp;
continue;
}
a[i][j]=temp;
}
printf(%d×%d魔方阵: ,M,M);
for(i=0;i<M;i++)
{
for(j=0;j<M;j++)
printf(%4d,a[i][j]);
printf( );
}
}
//(求4的倍数阶幻方)
void main()
{
int i,j,x,y,n,t,k=1;
int a[100][100];
printf(请输入魔方阵的阶数n );
scanf(%d,&n);
printf(输出为: );
if(n%4==0)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
a[i][j]=k;
k++;
}
x=n-1;
for(j=0;j<n/2;j++,x--)
{
for(i=0;i<n;i++)
if(i%4!=j%4&&(i+j)%4!=3)
{
t=a[i][j];
a[i][j]=a[i][x];
a[i][x]=t;
}
}
x=n-1;
for(i=0;i<n/2;i++,x--)
{
for(j=0;j<n;j++)
if(i%4!=j%4&&(i+j)%4!=3)
{
t=a[i][j];
a[i][j]=a[x][j];
a[x][j]=t;
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf(%-4d,a[i][j]);
printf( );
}
}
else printf(输入错误 );
system(pause...);
}

Ⅵ 4阶幻方的解法,详细的

解法1.(对称交换法)

1.求幻和

(12……16)÷4=34

2.

⑴将1~16按自然顺序排成四行四列;

⑵因为每条对角线上四个数之和恰为幻和,保持不动.

⑶将一四行交换、二三行交换,但是对角线上八个数不动。

⑷将一滑橘四列交换、二三列交换,但是对角线上八个数不动。

(1)

1 2 3 4

5 6 7 8

9 101112

13141516

(2)

114 15 4

9 6 7 12

5 10 118

13 2 316

(3)

1 15144

12 6 79

8 10115

13 3216

解法2.(田格图阵法)

1.将1~16平均分为4组,每组4个数的和均为幻和34.(多种分法)如:

112714=211813=310516=49615=34.

2.分别填入4个田字格,两行之和分别为13与21.

3.将4个田格合并,再适当转动各田格,得到满足要求的段让顷幻方.

解法3:(推理法)

常用,虽然速度不是很快。其实就是在1~16这16个数找到四个数相加为34的数填在四阶幻方的正中间,然后按照一定的推理方法填入其它空格内。

(方法挺笨重,但挺实用的握陆)

解法4:(方程法)

四阶幻方,可以有设置5个未知数到里面,只要代进其中的数,可以推出其它的数,具体设置位置,可以看下附图(应该上传的得了)

解法5:程序法

计算机的运算速度非常快,所以采用程序计算可以很快得到,至于什么样的程序,可以根据很多不同的算法得到每一种方法。举个例子,用程序法解三阶幻方,可以用“楼梯法”的精髓思想,也可以用“杨辉法”的精髓思想。

Ⅶ 四阶幻方的解法

四阶(加法)幻方很容易制。

第一步:选数。选取十六个数,把所选的十羡带六个数按一定顺序排列成四行四阶的方阵,如果每一行、每一列的数都成等差数列,那么用这十六个数就能制成四阶幻方。下面以1、2、3、4……15、16这十六个数为例说明四阶幻方的制法。

第二步:把这十六个数按顺序填入四行四列的方阵。

上面的三步做完,四阶幻方就完成了。

幻方制作完成后,对称地交换两行数或者两列数(如交换第一行与第四行、第二行与第三行),幻方仍然成立。

Ⅷ 请教4阶幻方的求解方法

四阶幻方的方法很多种,其中最简单的方法:【顺序填数,以中心点对称互换数字】。

互换数字的方法有两种:

1、互换对角线上的数;

2、互换非对角线上的数。

(8)求解四阶幻方的C语言扩展阅读

起源记载

在一个由若干个排列整齐的数组成的正方形中,图中任意一横行、一纵行及对角线的几个数之和都相等,具有这种性质的图表,称为“幻方”。中国古代称为“河图”、“洛书”,又叫“纵横图”。

九宫洛书蕴含奇门遁甲的布阵之道。九宫之搭陪数源于《易经》。幻方也称纵横图、魔方、魔阵,它是科学的结晶与吉祥的象征,发源于中国古代的洛书——九宫图。

公元前一世纪,西汉宣帝时的博士戴德在他的政治礼仪着作《大戴礼·明堂篇》中就有“二、九、四、七、五、三、六、一、八”的洛书九宫数记载。洛书被世界公认为组合数学的鼻祖,它是中华民族对人类的伟大贡献之一。

洛书以其高度抽象的内涵,对中国古代政治伦理、数学、天文气象、哲学、医学、宗教等都产生了重要影响。

在远古传说中,于治国安邦上也具有积极的寓意!包括洛书在内的幻方自古以来在亚、欧、美洲不少国家都被作为驱邪避凶的吉祥物,这种古代地域广泛的图腾应该说是极其少见的。1975年上海人民出版社出版的自然辩证法丛书《自然科学大事年表》,

《大戴礼》记载,中国古代有象征吉祥的河图洛书纵横图,即为九宫算,被认为是现代‘组合数学’最古老的发现。”

2500年前,孔子在他研究《易经》的着作《系词上传》中记载了:“河出图,洛出书,圣人则之。”最早将数字与洛书相连的记载是2300年前的《庄子·天运》,它认为:“天有六极五常,帝王顺之则治,逆之则凶。九洛之事,治成德备,监照下土,天下戴之,此谓上皇。”

明代数学家程大位在《算法统宗》中也曾发出“数何肇?其肇自图、书乎?伏羲得之以画卦,大禹得之以序畴,列圣得之以开物”的感叹,大意是说,数起源于远古时代黄河出现的河图与洛水出现的洛书知郑蠢,伏羲依靠河图画出八卦,大禹按照洛书划分九州,并制定治理天下的九类大法。

大禹从洛书中数的相互制约,均衡统一得到启发而制定国家的法律体系,使得天下一统,归于大治,这是借鉴思维的开端。这种活化思维的方式已成为科学灵感的来源之一。从洛书发端的幻方在数千年后更加生机盎然,被称为具有永恒魅力的数学问题。

十三世纪,中国南宋数学家杨辉在世界上首先开展了对幻方的系统研究,欧洲十四世纪也开丛早始了这方面的工作。着名数学家费尔玛、欧拉都进行过幻方研究,

如今,幻方仍然是组合数学的研究课题之一,经过一代代数学家与数学爱好者的共同努力,幻方与它的变体所蕴含的各种神奇的科学性质正逐步得到揭示。它已在组合分析、实验设计、图论、数论、群、对策论、纺织、工艺美术、程序设计、人工智能等领域得到广泛应用。

1977年,4阶幻方还作为人类的特殊语言被美国旅行者1号、2号飞船携入太空,向广袤的宇宙中可能存在的外星人传达人类的文明信息与美好祝愿。

Ⅸ 求C语言编写四阶幻方程序!用数组!

#include<银森stdio.h>
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");
}
}
你最好去看一下锋巧亩幻方的规律!