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

魔方又称幻方、纵横图、九宫图,最早记录于我国古代的洛书。据说夏禹治水时,河南洛阳附近的大河里浮出了一只乌龟,背上有一个很奇怪的图形,古人认为是一种祥瑞,预示着洪水将被夏禹王彻底制服。后人称之为"洛书"或"河图",又叫河洛图。
南宋数学家杨辉,在他著的《续古摘奇算法》里介绍了这种方法:只要将九个自然数按照从小到大的递增次序斜排,然后把上、下两数对调,左、右两数也对调;最后再把中部四数各向外面挺出,幻方就出现了。 (摘自《趣味数学辞典》)
在西方,阿尔布雷特·丢勒于1514年创作的木雕《忧郁》是最早关于魔方矩阵的记载。有学者认为,魔方矩阵和风靡一时的炼金术有关。几个世纪以来,魔方矩阵吸引了无数的学者和数学爱好者。本杰明·富兰克林就做过有关魔方矩阵的实验。
最简单的魔方就是平面魔方,还有立体魔方、高次魔方等。对于立体魔方、高次魔方世界上很多数学家仍在研究,本文只讨论平面魔方。
每行、每列及对角线之和被称为魔术常量或魔法总和,M。
其中,n为阶数。
例如,如果n=3,则M=[3*(3^2+1)]/2 = 15.

------------------来自百度

 

先标出引用地址:

http://blog.ddedu.com.cn/user1/88/archives/2007/2007420143329.shtml   //任意阶幻方构造方法

http://blog.csdn.net/cmutoo/article/details/5487157                                  //任意阶幻方C语言代码实现(有些许错误)

 

基础知识这里看:http://blog.csdn.net/oowgsoo/article/details/1567910

 

任意阶幻方的构造方法有很多种,所以要选定一种易于代码实现的一种

在上篇博客中说道:

/************************************************************************************

幻方的数量:
与我们大多数人的常识不同,幻方的数量不是唯一的,而且也不是一个简单的问题
3阶幻方只有1种
4阶幻方有880种,通过旋转和反射,总共可以有7040个幻方
5阶幻方有275 305 224个,这是用计算机算的
6阶幻方,大概是1.7743*10**19~1.7766*10**19之间,这是用统计学方法计算的,居然计算机也算不出来,更不要说6阶以上的幻方数量了

************************************************************************************/

所以代码实现的就有很大的局限性,只能实现某一种构造方法的幻方

幻方构造分为

1、奇数阶

2、双偶阶

3、单偶阶

三种。

对于奇数阶的幻方:

/*******************************************************************

n为奇数 (n=3,5,7,9,11……) (n=2×k+1,k=1,2,3,4,5……)
奇数阶幻方最经典的填法是罗伯特法(也有人称之为楼梯法)。填写方法是这样:
  把1(或最小的数)放在第一行正中; 按以下规律排列剩下的n×n-1个数:
  (1)每一个数放在前一个数的右上一格;
  (2)如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;
  (3)如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;
  (4)如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在前一个数的下一行同一列的格内;
  (5)如果这个数所要放的格已经有数填入,处理方法同(4)。
  这种写法总是先向“右上”的方向,象是在爬楼梯。
*******************************************************************/
其实在C语言实现时是有潜在的规律的,当要填的数为n的倍数时,说明所要放的格已经有数填入
实现过程也是很巧妙……
void Odd(int n,int index)
{while(st != index){cube[ox+stx][oy+sty] = st++;if((st-1) % n != 0){stx--;sty++;}else{stx++;}stx = ((stx-1)%n+n)%n+1;sty = (sty%n == 0 ? n : sty%n);}
}

对于双偶数阶的

就是一个中心对称

void DouEven(int n)
{int i,j;int st = 1;for(i=1; i<=n; i++){for(j=1; j<=n; j++){cube[i][j] = st++;}}int zx,zy,fx,fy;for(i=4; i<=n*n; i+=4){for(j=4; j<=n*n; j+=4){zx=i-3,zy=j-3,fx=i,fy=j-3;cube[zx][zy]=n*n-cube[zx][zy]+1;cube[zx+1][zy+1]=n*n-cube[zx+1][zy+1]+1;cube[zx+2][zy+2]=n*n-cube[zx+2][zy+2]+1;cube[zx+3][zy+3]=n*n-cube[zx+3][zy+3]+1;cube[fx][fy]=n*n-cube[fx][fy]+1;cube[fx-1][fy+1]=n*n-cube[fx-1][fy+1]+1;cube[fx-2][fy+2]=n*n-cube[fx-2][fy+2]+1;cube[fx-3][fy+3]=n*n-cube[fx-3][fy+3]+1;}}
}

对于单偶数阶的,麻烦许多

因为要用到奇数阶的构造方法

void SingleEven(int n)
{int i,j;ox=oy=0;st=1;stx=1,sty=(n/2+1)/2;Odd(n/2,n*n*1/4+1);    //A
ox=oy=n/2;stx=1,sty=(n/2+1)/2;Odd(n/2,n*n*2/4+1);    //D
ox=0,oy=n/2;stx=1,sty=(n/2+1)/2;Odd(n/2,n*n*3/4+1);    //B
ox=n/2,oy=0;stx=1,sty=(n/2+1)/2;Odd(n/2,n*n*4/4+1);    //Cint k=(n-2)/4,tmp;for(j=1; j<=n/2; j++){for(i=1; i<=k; i++){if(j != (n/2+1)/2){tmp = cube[j][i];cube[j][i] = cube[j+n/2][i];cube[j+n/2][i] = tmp;}else{tmp = cube[j][i+(n/2+1)/2-1];cube[j][i+(n/2+1)/2-1] = cube[j+n/2][i+(n/2+1)/2-1];cube[j+n/2][i+(n/2+1)/2-1] = tmp;}}}if(k-1){for(i=1; i<=n/2; i++){int tmpp = (3*n+2)/4-1;for(j=1; j<=k-1; j++){tmp = cube[i][j+tmpp];cube[i][j+tmpp] = cube[i+n/2][j+tmpp];cube[i+n/2][j+tmpp] = tmp;}}}
}

 

最后贴一个完整的代码:

#include <stdio.h>
#include <string.h>int cube[1000][1000];
int stx,sty;
int st;
int num;
int ox,oy;void Odd(int n,int index)
{while(st != index){cube[ox+stx][oy+sty] = st++;if((st-1) % n != 0){stx--;sty++;}else{stx++;}stx = ((stx-1)%n+n)%n+1;sty = (sty%n == 0 ? n : sty%n);}
}void DouEven(int n)
{int i,j;int st = 1;for(i=1; i<=n; i++){for(j=1; j<=n; j++){cube[i][j] = st++;}}int zx,zy,fx,fy;for(i=4; i<=n*n; i+=4){for(j=4; j<=n*n; j+=4){zx=i-3,zy=j-3,fx=i,fy=j-3;cube[zx][zy]=n*n-cube[zx][zy]+1;cube[zx+1][zy+1]=n*n-cube[zx+1][zy+1]+1;cube[zx+2][zy+2]=n*n-cube[zx+2][zy+2]+1;cube[zx+3][zy+3]=n*n-cube[zx+3][zy+3]+1;cube[fx][fy]=n*n-cube[fx][fy]+1;cube[fx-1][fy+1]=n*n-cube[fx-1][fy+1]+1;cube[fx-2][fy+2]=n*n-cube[fx-2][fy+2]+1;cube[fx-3][fy+3]=n*n-cube[fx-3][fy+3]+1;}}
}void SingleEven(int n)
{int i,j;ox=oy=0;st=1;stx=1,sty=(n/2+1)/2;Odd(n/2,n*n*1/4+1);    //A
ox=oy=n/2;stx=1,sty=(n/2+1)/2;Odd(n/2,n*n*2/4+1);    //D
ox=0,oy=n/2;stx=1,sty=(n/2+1)/2;Odd(n/2,n*n*3/4+1);    //B
ox=n/2,oy=0;stx=1,sty=(n/2+1)/2;Odd(n/2,n*n*4/4+1);    //Cint k=(n-2)/4,tmp;for(j=1; j<=n/2; j++){for(i=1; i<=k; i++){if(j != (n/2+1)/2){tmp = cube[j][i];cube[j][i] = cube[j+n/2][i];cube[j+n/2][i] = tmp;}else{tmp = cube[j][i+(n/2+1)/2-1];cube[j][i+(n/2+1)/2-1] = cube[j+n/2][i+(n/2+1)/2-1];cube[j+n/2][i+(n/2+1)/2-1] = tmp;}}}if(k-1){for(i=1; i<=n/2; i++){int tmpp = (3*n+2)/4-1;for(j=1; j<=k-1; j++){tmp = cube[i][j+tmpp];cube[i][j+tmpp] = cube[i+n/2][j+tmpp];cube[i+n/2][j+tmpp] = tmp;}}}
}void print(int n)
{int i,j;for(i=1; i<=n; i++){int sum = 0;for(j=1; j<=n ; j++){sum += cube[i][j];printf("%4d",cube[i][j]);}printf("    sum = %d",sum);printf("\n");}
}int main()
{int i,j,k,t,n,m;do{printf("Please Input n(3-17): ");scanf("%d",&n);if(n<3)continue;memset(cube,0,sizeof(cube));if(n % 2 == 1){stx=1,sty=(n+1)/2;ox=oy=0;st=1;Odd(n,n*n+1);print(n);}else if(n % 4 == 0){DouEven(n);print(n);}else if(n % 2 ==0 && n % 4 != 0){SingleEven(n);print(n);}}while(1);return 0;
}

再上一个专门关于介绍幻方的博客:http://blog.sina.com.cn/u/1225071715

 

转载于:https://www.cnblogs.com/ccccnzb/p/4017872.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android防谷歌滑动效果,谷歌是如何做到这一点的?在Android应用程序中滑动ActionBar...

事实上&#xff0c;有一种方法可以做到这一点。即使没有实施自己的ActionBar。看看hierachyviewer吧&#xff01;(位于工具目录中)还有的DecorView&#xff0c;并且LinearLayout作为一个孩子。这LinearLayout包含ActionBar其他内容和其他内容。所以&#xff0c;你可以简单地应用…

thinkphp框架使用心得

接触的第一个PHP框架就是TP&#xff0c;在使用的了一段时间后就放弃了&#xff0c;说实话TP的弊端挺多&#xff0c;之后又接触laravel框架&#xff0c;慢慢的就爱上laravel这个框架了。这段时间由于公司的原因&#xff0c;又不得不使用thinkphp框架,在这里分享下使用心得。 TP框…

计算本年 本月 本周的起始日期

html: <table><tr><td align"right" width"120px"> 销售时间区间:</td><td><select id"ddlChoiceDate" name"ddlChoiceDate" runat"server" onchange"SelectChange(this.value);&quo…

Android查看真机布局,android-外部存储

外部存储&#xff0c;个人理解是在app作用域之外存储&#xff0c;就是数据没有和app做关联&#xff0c;app卸载后&#xff0c;它依旧存在而不再是之前手机本身存储空间和sd卡的区别&#xff0c;现在安卓手机已经不携带可拆卸的SD卡androidManifest.xml 需要写入读写权限简单布局…

用自己的ID在appstore中更新app-黑苹果之路

由于之前套用了别人的镜像&#xff0c;在appstore中更新XCode时总要输别人id的密码&#xff0c;id还不能改。网上有的说要把XCode删掉&#xff0c;然后再用自己的ID更新&#xff0c;找到另外一个方法&#xff0c;更简单&#xff1a; 1.打开引用程序目录 2.找到Xcode&#xff0c…

如何打开pr_debug调试信息

转载&#xff1a;http://blog.csdn.net/helloanthea/article/details/25330809 以DMA的调试为例&#xff0c;先来看看一个pr_debug函数调用 pr_debug("%s: %s (%s)\n",__func__,chan ? "success" : "fail",chan ? dma_chan_name(chan) : NULL)…

android国籍组件,android组件化之路

问题&#xff1a;实际业务变化快&#xff0c;而工程内各个功能模块耦合度太高&#xff0c;不能对功能模块进行快速方便地拆分或组装。团队共同开发中&#xff0c;可能一个文件同时被多人修改&#xff0c;导致每次更新提交代码都需要消耗大量时间去merge代码。每次修改&#xff…

UNIX环境编程学习笔记(21)——进程管理之获取进程终止状态的 wait 和 waitpid 函数...

lienhua342014-10-12 当一个进程正常或者异常终止时,内核就向其父进程发送 SIGCHLD信号。父进程可以选择忽略该信号,或者提供一个该信号发生时即被调用的函数(信号处理程序)。对于这种信号的系统默认动作是忽略它。 在文档“进程控制三部曲”中,我们讲的第三部曲是使用 wait 函…

poj2750 PottedFlower(线段树的环状操作)

题目&#xff1a;Potted Flower 大意&#xff1a;该你一个换环&#xff0c;求环上的最大连续的和&#xff08;如果最大和包含所有数&#xff0c;要求减去最小的一个&#xff09;。 思路&#xff1a;这道题的思路并不难&#xff0c;需要在线段树里维护区间的最大和&#xff0c…

android代码导入有错误,android新项目导入后进行编译出现cmake错误

问题描述使用as加载并且gradle sync 提示&#xff1a;SIMPLE:error configure同时使用make project提示问题出现的环境背景及自己尝试过哪些方法已经尝试更换过ndk 调整target brinary 然后完全clean project等操作相关代码// 请把代码文本粘贴到下方(请勿用图片代替代码)使用g…

简单排序算法设计(Java)

总共有八种排序算法&#xff0c;还是慢慢看吧 1、简单排序算法 简单排序算法就是设置标兵&#xff0c;逐个比较数&#xff0c;然后查找插入位置&#xff0c;插入 public static void p(int[] a){for(int i0;i<a.length;i){System.out.print(a[i]" ");}}public sta…

cocos2d-x坐标系

在cocos2d-x在&#xff0c;有几种不同的坐标系。因为有好几个坐标系着一定的差异&#xff0c;他们需要明白&#xff0c;能力更精确的绘制各种图形画面上。 1.屏幕坐标系 只windows通过绘制图形上基本都知道。相应的坐标系统&#xff1a;原点在左上角。向右是x轴正方向&#xff…

android收入管理系统,毕业设计(论文)-基于Android系统的家庭理财通软件的设计——收入管理模块.docx...

PAGE河北农业大学信息学院本科毕业论文题 目&#xff1a;基于Android系统的家庭理财通软件的设计——收入管理模块学 院&#xff1a; 信息科学与技术学院专业班级&#xff1a; 计算机科学与技术0902班学 号&#xff1a;二O一三 年 五 月 二十八 日摘 要基于安卓系统的家庭理财通…

BZOJ1652 [Usaco2006 Feb]Treats for the Cows

蒟蒻许久没做题了&#xff0c;然后连动规方程都写不出了。 参照iwtwiioi大神&#xff0c;这样表示区间貌似更方便。 令f[i, j]表示i到j还没卖出去&#xff0c;则 f[i, j] max(f[i 1, j] v[i] * T, f[i, j - 1] v[j] * T) &#xff08;←这样用推的方式更好想一点。。&#…

android系统提供了url通信,Android两种HTTP通信,HttpURLConnection和HttpClient

Android系统中主要提供了两种方式来进行HTTP通信&#xff0c;HttpURLConnection和HttpClient&#xff0c;几乎在任何项目的代码中我们都能看到这两个类的身影&#xff0c;使用率非常高。不过HttpURLConnection和HttpClient的用法还是稍微有些复杂的&#xff0c;如果不进行适当封…

ECSHOP 订单状态 记录

记录订单状态 order_status /* 订单状态 */ define(‘OS_UNCONFIRMED’, 0); // 未确认 define(‘OS_CONFIRMED’, 1); // 已确认 define(‘OS_CANCELED’, 2); // 已取消 define(‘OS_INVALID’, 3); // 无效 define(‘…

git+jekyll部署备忘

github&#xff0c;会自动帮忙编译jekyll编写的文件&#xff0c;只要将文件放到gh-pages分支 (或者使用官方教程的二级域名方式&#xff0c;项目名字&#xff0c;可以随便起&#xff0c;官网的例子是 用户名.github.com 作为项目名字&#xff0c;可以使用 用户名.github.com …

buidulbs android.jar,在将AS项目迁移到IDEA时,无法将com.android.bui...

我需要从Android Studio迁移到IntelliJ IDEA,因为我需要在Java中进行其他一些非Android的工作.我从git克隆了我的项目,并将其导入到IDEA中.但是,我在此过程中遇到了Gradle错误.我已经搜索过,但是找不到解决我的错误的答案.这是事件日志03:39:42 PM All files are up-to-date03:…

[华为机试练习题]60.水仙花数

题目 描述: 水仙花数又称阿姆斯特朗数。 水仙花数是指一个n 位数( n≥3 )&#xff0c;它的每个位上的数字的n 次幂之和等于它本身。&#xff08;例如&#xff1a;1^3 5^3 3^3 153&#xff09; 求输入的数字是否为水仙花数练习阶段: 初级 代码 /*-------------------------…

fscanf的返回值未成功输入的元素个数 .xml

test.txt 中保存的为&#xff1a;12345程序int i,j,k; FILE *fpfopen("e://test.txt","r"); if (fpNULL) { //return FALSE; } while (!feof(fp)) { jfscanf(fp,"%d%d",&i,&k); cout<<i<</t<<k<</t<…