码迷,mamicode.com
首页 > 编程语言 > 详细

任意阶幻方的c++实现----奇阶幻方、双偶幻方、单偶幻方。

时间:2014-09-20 16:42:49      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:算法   幻方   

幻方分为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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!