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

幻方分为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;
}
时间: 2024-12-23 17:09:31

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

神奇的幻方【够造奇数阶的魔方阵】

http://noi.openjudge.cn/ch0108/22/ 总时间限制:  1000ms 内存限制:  65535kB 描述 幻方是一个很神奇的N*N矩阵,它的每行.每列与对角线,加起来的数字和都是相同的.我们可以通过以下方法构建一个幻方.(阶数为奇数)1.第一个数字写在第一行的中间2.下一个数字,都写在上一个数字的右上方:    a.如果该数字在第一行,则下一个数字写在最后一行,列数为该数字的右一列    b.如果该数字在最后一列,则下一个数字写在第一列,行数为该数字的上一行    

幻方的构造模板

/* 幻方的计算: 计算任意阶数幻方的各行.各列.各条对角线上所有数的和的公式为:sum=n*(n^2+1)/2 n为阶数 幻方分为奇阶幻方和偶阶幻方 一.当n为奇数时称为奇阶幻方 1.Merzirac法生成奇阶幻方 在第一行居中的方格内放1,依次向右上方填入2.3.4…,如果右上方已有数字,则向下移一格继续填写. 2.loubere法生成奇阶幻方 在居中的方格向上一格内放1,依次向右上方填入2.3.4…,如果右上方已有数字,则向上移两格继续填写 3.horse法生成奇阶幻方 (1)对于所有的奇

任意阶幻方(魔方矩阵)C语言实现

魔方又称幻方.纵横图.九宫图,最早记录于我国古代的洛书.据说夏禹治水时,河南洛阳附近的大河里浮出了一只乌龟,背上有一个很奇怪的图形,古人认为是一种祥瑞,预示着洪水将被夏禹王彻底制服.后人称之为"洛书"或"河图",又叫河洛图. 南宋数学家杨辉,在他著的<续古摘奇算法>里介绍了这种方法:只要将九个自然数按照从小到大的递增次序斜排,然后把上.下两数对调,左.右两数也对调:最后再把中部四数各向外面挺出,幻方就出现了. (摘自<趣味数学辞典>) 在西方

Java 实现任意N阶幻方的构造

一.关于单偶数阶幻方和双偶数阶幻方 (一)单偶数阶幻方(即当n=4k+2时) 任何4k+2 阶幻方都可由2k+1阶幻方与2×2方块复合而成,6是此类型的最小阶. 以6阶为例,可由3阶幻方与由0,1,2,3组成的2×2的小方块拼成一个6×6的大方块复合而成. 其中,3阶幻方(洛书)如下图1所示, (图1) 800x600 Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE MicrosoftInternetExplorer4 /* Sty

任意阶魔方阵(幻方)的算法及C语言实现

写于2012.10: 本来这是谭浩强那本<C程序设计(第四版)>的一道课后习题,刚开始做得时候去网上找最优的算法,结果发现奇数和双偶数(4的倍数)的情况下算法都比较简单,但是单偶数(2的倍数但不是4的倍数)情况一直找不到明确的算法,就连百度百科对这一问题的解释也是“因非四的倍数作法相当复杂,在此只介绍四的倍数的作法”,而且连谭浩强那本书给的答案中竟然也变相的限定了n只能为奇数(题目并未说明).在广泛查找资料后,发现了一篇由中南大学信息科学与工程学院某教授和研究生撰写的论文,介绍了任意阶幻方的算

n阶幻方问题

转载自:http://blog.csdn.net/fengchaokobe/article/details/7437767 目录        第一节 n阶幻方问题       第二节 由n阶幻方引发的思考 正文 第一节 n阶幻方问题 所谓n阶幻方问题,俗称“横竖斜相加和相等”(我们当时就是这么叫的).用术语说就是:在一个N行N列的方格表中,有1,2,3......N*N-1,N*N这N*N个整数,且其对角线.横行.纵行的数字和都相等.       好了,在具体详解该问题之前,我们先看个例子,熟

5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器

一.什么是装饰器? 实际上装饰器就是个函数,这个函数可以为其他函数提供附加的功能. 装饰器在给其他函数添加功能时,不会修改原函数的源代码,不会修改原函数的调用方式. 高阶函数+函数嵌套+闭包 = 装饰器 1.1什么是高阶函数? 1.1.1函数接收的参数,包涵一个函数名. 1.1.2 函数的返回值是一个函数名. 其实这两个条件都很好满足,下面就是一个高阶函数的例子. def test1(): print "hamasaki ayumi" def test2(func): return t

聊聊React高阶组件(Higher-Order Components)

使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低的东西如今可不多见了啊,是个不可多得的 zhuangbility的利器,自然不可轻易错过,遂深入了解了一番. 概述 高阶组件的定义 React 官网上对高阶组件的定义: 高阶部件是一种用于复用组件逻辑的高级技术,它并不是 React API的一部分,而是从React 演化而来的一种模式. 具体地说,

n阶魔方阵(奇数阵)的输出

需求 要求输出1~n2的自然数构成的魔方阵. STEP 1 什么是魔方阵? 魔方阵,古代又称"纵横图",是指组成元素为自然数1.2-n2的平方的n×n的方阵,其中每个元素值都不相等,且每行.每列以及主.副对角线上各n个元素之和都相等. STEP 2 魔方阵的规律是什么? 此处先写简单一点的奇阶魔方阵,偶数阶的算法更复杂,暂不讨论. 奇阶魔方阵的排列方法: ⑴将1放在第一行中间一列: ⑵从2开始直到n×n止各数依次按下列规则存放:每一个数存放的行比前一个数的行数减1,列数加1: ⑶如果上