幻方分为3类。奇阶幻方(奇数)、双偶幻方(能够被4整除,如8,12,16……)、单偶幻方(4m+2形式,如6,10……),构造算法各不相同。
下面的程序中,奇阶幻方的构造算法为Merzirac法。双偶幻方的构造算法为Spring法。单偶幻方的构造算法为Strachey法。
单偶幻方:
在第一行居中的方格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向下移一格继续填写。
参考:http://blog.csdn.net/zheng0518/article/details/9006281
双偶幻方:
(1) 先把数字按顺序填。然后,按4*4把它分割成2*2个小方阵 。
(2) 每个小方阵对角线上的数字,换成和它互补的数。
参考:http://chenxuebiao3.blog.163.com/blog/static/274911182011111911429621/
单偶幻方:
参考:http://blog.sina.com.cn/s/blog_639b95e90100i6h4.html
各行列对角线的和公式为:sum=n*(n^2+1)/2 n为阶数
代码如下:
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
int matrix[99][99] = {0};
//生成奇数幻方
void CreateOddMagicSquare(int n)
{
int x=0,y,mun =1;
y=n/2;
while ( mun <= n*n )
{
matrix[x][y] = mun;
//通过x0、y0检测右上的是否已经填入数字
int x0=x;
int y0=y;
x0--;
y0++;
//超界处理
if(x0<0)
x0+=n;
if(y0 == n)
y0= n - y0;
if(0 == matrix[x0][y0] )
{
x = x0;
y = y0;
}
else
{
//若有数字填入之前数字的下方
x++;
if(x == n)
x = x-n;
}
mun ++;
}
}
//生成双偶幻方
void CreateDoubleEvenMagicSqure( int n )
{
int num = 1;
//从1到n的平方依次赋值
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
matrix[i][j] = num++ ;
//小正方形的对角线上的数字取其补数
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(i%4==0 && abs(i-j)%4 == 0)
for(int k=0;k<4;k++)
matrix[i+k][j+k] = abs( n*n +1 - matrix[i+k][j+k] );
else if (i%4==3 && (i+j)%4 == 3)
for(int k=0;k<4;k++)
matrix[i-k][j+k] = abs( n*n +1 - matrix[i-k][j+k] );
}
}
//生成单偶幻方
void CreateSingleEvenMagicSqure(int n)
{
int k = n/2;
CreateOddMagicSquare(k);
//赋初值,左上最小,右下其次,右上再次,左下最大
for(int i=0;i<k;i++)
for(int j=0;j<k;j++)
{
matrix[i+k][j+k] = matrix[i][j] + k*k;
matrix[i][j+k] = matrix[i][j] + k*k*2;
matrix[i+k][j] = matrix[i][j] + k*k*3;
}
//公式 n=4m+2
int m = (n-2) / 4;
//交换x方向正中行的从左至右m-1个
for(int i=0;i<m-1;i++)
{
int buf = matrix[k/2][i];
matrix[k/2][i] = matrix[k/2+k][i];
matrix[k/2+k][i] = buf;
}
int buf = matrix[k/2][k/2];
//以及正中间的数
matrix[k/2][k/2] = matrix[k/2+k][k/2];
matrix[k/2+k][k/2] = buf;
//交换除x正中间行的其他行对应数字m个
for(int i=0;i<k;i++)
for(int j=0;j<k/2;j++)
{
if(i != k/2)
{
int buf = matrix[i][j];
matrix[i][j] = matrix[i+k][j];
matrix[i+k][j] = buf;
}
}
//交换最右边m-1个数字
for(int i=0;i<k;i++)
for(int j=n-1;j>n-1-(m-1) ; j--)
{
int buf = matrix[i][j];
matrix[i][j] = matrix[i+k][j];
matrix[i+k][j] = buf;
}
}
//幻方正确检查
bool Check(int n)
{
int sum = (n*(n*n+1))/2;
int SumA=0,SumB=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
SumA += matrix[i][j];
if(SumA != sum)
return false;
SumA = 0;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
SumA += matrix[j][i];
if(SumA != sum)
return false;
SumA = 0;
}
for(int i=0;i<n;i++)
{
SumA+=matrix[i][i];
SumB+=matrix[i][n-i-1];
}
if(SumA!=sum||SumB!=sum)
return false;
return true;
}
int main()
{
int n;
cin>>n;
if(n%2!=0)
CreateOddMagicSquare(n);
else if (n%4 == 0)
CreateDoubleEvenMagicSqure(n);
else if (n%2 == 0)
CreateSingleEvenMagicSqure(n);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
cout<<matrix[i][j]<<"\t";
cout<<endl<<endl;
}
if(!Check(n))
cout<<"the ans is wrong"<<endl;
else
cout<<"right answer"<<endl;
system("pause");
return 1;
}
任意阶幻方的c++实现----奇阶幻方、双偶幻方、单偶幻方。
原文地址:http://blog.csdn.net/zzukun/article/details/39431303