snjsj 我的程序算法:
这个魔方阵的算法可以对除2以外的任意阶数的方阵进行输出,结果保存在运行程序的目录下面的Magic.txt文件中,用ie或者写字板打开以保持格式的一致(主要是回车符在记事本中为黑方框,认不出来)。当然具体的程序中,有内存空间以及变量范围的约束,我试过了,100以内的是可以的。
偶数阶的算法都是建立在奇数阶的基础之上,设方阵的阶数为n,则魔方阵常数(即每列每行以及对角线元素之和)为n*(n*n+1)/2。
请对照程序代码看,否则可能看不懂,可以一边看一边用笔对小阶的进行演算。
先说奇数阶的算法,这是最容易的算法:
n=2*m+1,m为自然数
1)将数字1填在(0,(n+1)/2) ;要注意c中是从下标0开始
2)从左上往右下依次填。
3)由2),列的下标出界(超过n-1)时,行加1,以n为摸的余数为应填的列数;
4)由2),行的下标出界(超过n-1)时,列加1,以n为摸的余数为应填的行数;
5)由2),行列都未出界,但已添上其他数,应在当前位置左横移一个位置进行填数。
然后是偶数阶:
分两种情况,一种是n%4==2,一种是n%4==0
前一种:n=2*(2*m+1),m为自然数
1)将n阶方阵分为四个小魔方阵ABCD如下排列:
B C
D A
因为n*n=4*(2*m+1)*(2*m+1),
记u=n/2=2*m+1,分为1~u*u,u*u+1~2*u*u,2*u*u+1~3*u*u,3*u*u+1~4*u*u
即在调用子函数的时候分别如下面传递参数:
A(0),B(u*u),C(2*u*u),D(3*u*u)
分别在ABCD中按照前面的填法把奇数阶填好(注意加上所传参数作为基数,每一个元素都要加上这个值),最后做如下交换:
(1)B中第0~(m-1)-1行中元素与C中相对应元素交换
(2)D中第(n-1)-m+1~(n-1)共m行的每行中的元素与A中相对应元素交换
(3)交换D:(u+m,m)与A中对应元素(矩阵中心值)
(4)交换D:(n-1,m)与A中对应元素(实际为矩阵最大值n*n)
所谓对应位置,指相对于小魔方阵的左顶角的相对的行列位置
上面的这些你可以用数学进行证明,利用魔方阵常数(注意n阶的和u阶的关系)
后一种:n=4*m,m为自然数
因为行列都是4的倍数,因而可以将整个矩阵分为每4*4的小矩阵。
先判断一个数是否在划为4*4小矩阵的对角线上,
如果在,则填该位置的数为n*n-i+1(i为该元素的相对位置,从1开始,比如n阶的第s行第t个元素则其i=s*n+t)
如果不在,则填上i。
#include<stdio.h>
#include<stdlib.h>
int N;
int *M=NULL;
void main()
{
int i;
int check(int,int);
void out();
void set_3_5(int,int,int,int);
void set_4();
void set_6();
void swap(int,int);
printf("Press any key to start:");
getch();
printf("/r");
Begin:
printf("Input the rank of the Magic Matrix:");
scanf("%d",&N);
if(N<=2){printf("/007/n/nInput Error!Try again!/n");goto Begin;}
M=(int *)calloc(N*N+1,sizeof(int));
if(M==NULL)
{printf("/007/nError:Out of memory!/n");
goto Next;
}
for(i=0;i<N*N;i++){*(M+i)=0;}
switch(N%4)
{case 0:set_4();break;
case 2:set_6();break;
default:i=N;set_3_5(0,0,i,0);
}
out();
free(M);
Next:
printf("/nWould you like to go on?/nPress Esc to exit,any other key to continue:");
i=getch();
if(i!=27){putchar('/n');goto Begin;}
else printf("/007/nThanks for use./n");
}
int check(int i,int j)
{switch(i%4)
{case 0:
case 3:if(j%4==0||j%4==3)return(1);
else return(0);
default:if(j%4==1||j%4==2)return(1);
else return(0);
}
}
void set_3_5(int i0,int j0,int mod,int base)
{int i_try,j_try,k,i=0,j=mod/2;
*(M+(i+i0)*N+j+j0)=1+base;
for(k=2;!(k>mod*mod);k++)
{i_try=i-1,j_try=j-1;
if(i_try<0)i_try=mod-1;
if(j_try<0)j_try=mod-1;
if(*(M+(i_try+i0)*N+j_try+j0)||i==0&&j==0){i_try=i+1,j_try=j;}
i=i_try;j=j_try;
*(M+(i+i0)*N+j+j0)=k+base;
}
}
void set_4()
{int i,j,c=N*N;
for(i=0;i<N;i++)
{for(j=0;j<N;j++)
{if(check(i,j)){*(M+i*N+j)=c-i*N-j;}
else {*(M+i*N+j)=i*N+j+1;}
}
}
}
void set_6()
{int i,j,m,u;
u=N/2;
m=(u-1)/2;
set_3_5(0,0,u,u*u);
set_3_5(0,u,u,2*u*u);
set_3_5(u,0,u,3*u*u);
set_3_5(u,u,u,0);
for(i=0;i<m-1;i++)
for(j=0;j<u;j++)
swap(i,j);
for(i=0;i<m;i++)
for(j=0;j<u;j++)
swap(N-1-i,j);
swap(u+m,m);
swap(N-1,m);
}
void swap(int i,int j)
{int p=*(M+i*N+j);
*(M+i*N+j)=*(M+i*N+j+N/2);
*(M+i*N+j+N/2)=p;
}
void out()
{int i,j;
FILE *fp;
float c=(float)N*((float)N*(float)N+1)/2;
fp=fopen("Magic.txt","wb+");
if(fp==NULL)
{printf("Create file ERROR!/n");
exit(0);
}
else
printf("/007/nYou can find the result in the Magic.txt where you run the program./n");
for(i=0;i<N;i++)
{for(j=0;j<N;j++)
fprintf(fp,"%8d",*(M+i*N+j));
fprintf(fp,"/n");
}
fprintf(fp,"Magic Matrix rank=%d,Magic constant=%.0f./n",N,c);
fclose(fp);
}
#include<stdio.h>
#include<math.h>
#define n 9
long aver;
long chazhi(long a[n][n])
{long i,j,m=0,x=0;
for(i=0;i<n;i++)
{for(j=0;j<n;j++)x+=a[i][j];
m+=(x-aver)*(x-aver)*(x-aver)*(x-aver);x=0;}
for(j=0;j<n;j++)
{for(i=0;i<n;i++)x+=a[i][j];
m+=(x-aver)*(x-aver)*(x-aver)*(x-aver);x=0;}
for(i=0;i<n;i++)x+=a[i][i];
m+=(x-aver)*(x-aver)*(x-aver)*(x-aver);x=0;
for(i=0;i<n;i++)x+=a[i][n-i-1];
m+=(x-aver)*(x-aver)*(x-aver)*(x-aver);x=0;
return(m);
}
main()
{long a[n][n],i,j,k,t,s,m,jj,cha,b[n];
m=1;
for (i=0;i<n;i++)
for(j=0;j<n;j++){a[i][j]=m++;printf("%d/n",a[i][j]);}
m=0;
for(i=1;i<=n*n;i++)m+=i;
aver=m/n;printf("%d",aver);
cha=chazhi(a);printf("%8d/n",cha);
/*while(cha!=0)*/for(jj=0;jj<23;jj++)
{printf("%8d",cha);
for(i=0;i<n;i++)
{for(j=0;j<n;j++)b[j]=a[i][j];
t=chazhi(a);
for(j=1;j<n;j++)
{s=a[i][0];
for(k=0;k<n-1;k++)a[i][k]=a[i][k+1];
a[i][n-1]=s;
s=chazhi(a);
if(t>s)
{t=s;for(k=0;k<n;k++)b[k]=a[i][k];
}
}
for(j=0;j<n;j++)a[i][j]=b[j];
cha=t;
}
if(cha!=0)
{for(j=0;j<n;j++)
{for(i=0;i<n;i++)b[i]=a[i][j];
t=chazhi(a);
for(i=1;i<n;i++)
{s=a[0][j];
for(k=0;k<n-1;k++)a[k][j]=a[k+1][j];
a[n-1][j]=s;
s=chazhi(a);
if(t>s)
{t=s;for(k=0;k<n;k++)b[k]=a[k][j];
}
}
for(i=0;i<n;i++)a[i][j]=b[i];
cha=t;
}
}
if(cha!=0)
{for(i=0;i<n;i++)b[i]=a[i][i];
t=chazhi(a);
for(i=1;i<n;i++)
{s=a[0][0];
for(k=0;k<n-1;k++)a[k][k]=a[k+1][k+1];
a[n-1][n-1]=s;
s=chazhi(a);
if(t>s)
{t=s;for(k=0;k<n;k++)b[k]=a[k][k];
}
}
for(i=0;i<n;i++)a[i][i]=b[i];
cha=t;
}
if(cha!=0)
{for(i=0;i<n;i++)b[i]=a[i][n-i-1];
t=chazhi(a);
for(i=1;i<n;i++)
{s=a[0][n-1];
for(k=0;k<n-1;k++)a[k][n-k-1]=a[k+1][n-k-2];
a[n-1][0]=s;
s=chazhi(a);
if(t>s)
{t=s;for(k=0;k<n;k++)b[k]=a[k][n-k-1];
}
}
for(i=0;i<n;i++)a[i][n-i-1]=b[i];
cha=t;
}
}
printf("/n");
for(i=0;i<n;i++)
{for(j=0;j<n;j++)printf("%8d",a[i][j]);
printf("/n");
}
scanf("%c");
}
魔方矩阵
最新推荐文章于 2025-04-25 21:12:48 发布