所谓幻方,就是在一个nXn的正方形中,分别填上1到n*n的数字,使得每行每列以及对角线上的数字之和相等。比如,小学学过的九宫格就属于3阶幻方。幻方最早起源于中国。

对于幻方的求解,首先我们按照其阶数n(即一个边上有多少个格子)将其分为奇阶幻方和偶阶幻方,然后偶阶幻方又分为单偶幻方和双偶幻方。

奇阶幻方解法

奇阶幻方最简单的解法就是“罗伯法”,又称“楼梯法”。

具体步骤为:首先在第一行正中间的格子填1,然后就像走楼梯一样将2、3…n的数字依次填入右上角。这时可能会出现一个情况,就是超出了幻方的格子范围,当我们一直往右上角填的时候,如果是行超出了就行数加n,如果是列数超出了就列数减n,以保证数字始终在范围内。当填完1到n之后,开始填n+1到2*n。首先将n+1填到n的下面一格,然后再按走楼梯的方式填入n+2到2*n。如果中途出现超出范围的情况,同样按之前的方法处理。然后开始填2*n+1到3*n,首先将2*n+1填到2*n的下面一格,之后的都按之前的规律类推。

具体我们看下面的这个5阶幻方的例子:

首先,将第一行正中间填入1,然后2填在1的右上角。这时会发现,此时1的右上角超出格子了,我们可以将每列和每行看作一个环状。比如,第四列是一个连通的环,第四列第一个格子在向上走一格就到了第四列的最后一个格子,此时,这里填入2。然后2的右上角填入3,然后3的右上角填入4(同样的道理可将第三行看作环,那么4就填入了第三行的第一个格子),4的右上角填入5。这样就填完了前n个数,接下来我们填接下来的n个数,6直接填在5的下面一格,然后7填在6的右上角,8填在7的右上角,9填在8的右上角,10填在9的右上角。然后接下来的n个数也是如此,将11填在10的正下面,12填在11的右上角,剩下的依此类推。

双偶幻方解法

所谓双偶幻方即阶数n为4的倍数的幻方,这里用到的方法叫做“对称交换法”。

首先将1到n*n的数字,按行优先的顺序依次填满整个矩阵。

接下来将整个幻方完全划分成整数个4x4的大格子,然后如图

在每个4x4的大格子中都作这样的一个下标。最后,对于整个幻方(注意是整个)所有带有‘*’星号下标的数字进行一个统一的中心对称变换。

具体的例子我们看一个8阶幻方:

首先依次填入1到64,然后划分成一个个的4x4的大格子(这里我们用4种不同的颜色标出)。

然后我们标记相应的‘*’

最后对整体进行一个中心对称变换(简单地说,该格与中心的连线旋转180度)

结果为

单偶幻方解法

所谓单偶幻方就是阶数n为偶数但又不能被4整除的幻方,这里用到的方法叫做“象限对称交换法”。

首先将整个幻方分为四个象限

将1到n*n的数字也分成四组:1到n*n/4,n*n/4+1到n*n/2,n*n /2+1到3*n*n /4,3*n*n /4+1到n*n。

将这四组数分别按“罗伯法”填入到A、B、C、D四个象限中。

计算得到m=(n-2)/4。

将A象限正中的m格(即从A的最中间的格子开始从正中向右数m格)与D中相应部分(即对应的正中间的m格)平移互换。

然后A中另一部分(即不包括正中行的其他行,并且只换正中列以左的)也与D中相应部分(即对应处)平移互换。

C区中间m-1列(从中间列开始向右数共m-1列)与B中相应部分平移互换。

这里我们以10阶幻方为例:

首先我们按“罗伯法”填好A、B、C、D四个象限(注意分组填),如图。

然后A与D交换相应部分,C与B交换相应部分,这里用红色标出。

交换后为:

#include<stdio.h>
#define N 8      //阶数
int main()
{int x,y,a[N][N]={0},i=0,j,n,m;void change(int *a,int *b);if(N%2==1)          //奇阶幻方{for(j=0;j<N;j++){if(j==0&&i==0){x=0;y=N/2;a[x][y]=1;}else{a[x+1][y]=a[x][y]+1;x=x+1;}for(i=1;i<N;i++){x=x-1;y=y+1;if(y>N-1){y=y-N;}if(x<0){x=x+N;}a[x][y]=i+1+N*j;}}}else{if(N%4==0)                                //双偶幻方{for(i=0;i<N;i++)for(j=0;j<N;j++)a[i][j]=i*N+j+1;for(i=0;i<N/2;i++)for(j=0;j<N;j++){for(x=0,n=0;n<=N/4-1;n++){if(((i!=j+n*4)&&(i!=j-n*4))&&((i+j+n*4!=N-1)&&(i+j-n*4!=N-1)))x++;}if(x==N/4)change(&a[i][j],&a[N-i-1][N-j-1]);}}else                                   //单偶幻方{m=(N-2)/4;for(j=0;j<N/2;j++)               //A区{if(j==0&&i==0){x=0;y=N/4;a[x][y]=1;}else{a[x+1][y]=a[x][y]+1;x=x+1;}for(i=1;i<N/2;i++){x=x-1;y=y+1;if(y>N/2-1){y=y-N/2;}if(x<0){x=x+N/2;}a[x][y]=i+1+(N/2)*j;}}j=N/2,i=N/2;                    //B区for(j=N/2;j<N;j++){if(j==N/2&&i==N/2){x=N/2;y=3*N/4;a[x][y]=N*N/4+1;}else{a[x+1][y]=a[x][y]+1;x=x+1;}for(i=N/2+1;i<N;i++){x=x-1;y=y+1;if(y>N-1){y=y-N/2;}if(x<N/2){x=x+N/2;}a[x][y]=i-N/2+N*N/4+1+(N/2)*(j-N/2);}}j=0,i=N/2;for(j=0;j<N/2;j++)                //C区{if(j==0&&i==N/2){x=0;y=N*3/4;a[x][y]=2*N*N/4+1;}else{a[x+1][y]=a[x][y]+1;x=x+1;}for(i=N/2+1;i<N;i++){x=x-1;y=y+1;if(y>N-1){y=y-N/2;}if(x<0){x=x+N/2;}a[x][y]=i-N/2+2*N*N/4+1+(N/2)*j;}}j=N/2,i=0;for(j=N/2;j<N;j++)             //D区{if(j==N/2&&i==0){x=N/2;y=N/4;a[x][y]=3*N*N/4+1;}else{a[x+1][y]=a[x][y]+1;x=x+1;}for(i=1;i<N/2;i++){x=x-1;y=y+1;if(y>N/2-1){y=y-N/2;}if(x<N/2){x=x+N/2;}a[x][y]=i+3*N*N/4+1+(N/2)*(j-N/2);}}for(m=0;m<(N-2)/4;m++)change(&a[N/4][N/4+m],&a[N/4+N/2][N/4+m]);for(j=0;j<N/2;j++){if(j==N/4)continue;for(i=0;i<N/4;i++)change(&a[j][i],&a[j+N/2][i]);}for(m=0;m<(N-2)/4-1;m++){for(j=0;j<N/2;j++)change(&a[j][3*N/4+m],&a[j+N/2][3*N/4+m]);}}
}for(i=0;i<N;i++){for(j=0;j<N;j++)printf("%5d",a[i][j]);printf("\n");}return 0;
}
void change(int *a,int *b)
{int t;t=*a;*a=*b;*b=t;
}

(PS:直接扒的大一时候写的代码,有些地方编程可能不合理'(*>﹏<*)′)

转载请标明出处,原文地址:https://blog.csdn.net/come_from_pluto

幻方构造方法及C语言实现相关推荐

  1. java构造方法特点_java语言构造方法的特点是什么?和成员方法区别在哪?

    在科学技术水平发展日新月异的今时今日,大家对于新技术的渴求越来越强烈,也开始主动的学习更多的新知识以更好的适应时代的发展.今天就来为大家介绍一下java语言构造方法的特点是什么以及和成员方法区别在哪? ...

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

    魔方又称幻方.纵横图.九宫图,最早记录于我国古代的洛书.据说夏禹治水时,河南洛阳附近的大河里浮出了一只乌龟,背上有一个很奇怪的图形,古人认为是一种祥瑞,预示着洪水将被夏禹王彻底制服.后人称之为&quo ...

  3. java 偶数求和 数组_JAVA实现幻方

    作者:刘亮 幻方(Magic Square)是一种将数字安排在正方形格子中,使每行.列和对角线上的数字和都相等的方法. 幻方也是一种中国传统游戏.旧时在官府.学堂多见.它是将从一到若干个数的自然数排成 ...

  4. [转载] Java默认构造方法

    参考链接: Java 8中的默认方法 默认构造方法是Java语言的一种语法,是指没有参数的构造方法,可以分为2种:隐含的.程序中显式定义的. 1.默认构造方法 在java语言中,每个类至少有一个构造方 ...

  5. c++ string replace_JAVA应用程序开发之String类常用API

    [本文详细介绍了JAVA应用开发中的String类常用API,欢迎读者朋友们阅读.转发和收藏!] 1 基本概念 API ( Application Interface 应用程序接口)是类中提供的接口, ...

  6. 反射应用--取得类的结构

    1,目标: 通过反射取得类的全部接口, 取得类所继承的父类 取得类全部构造方法 通过反射取得类的全部方法 通过反射取得一个类的全部属性. 具体类型 反射的深入-取得类的结构 要想通过反射取得类的结构, ...

  7. JavaSE学习总结(六)——接口、抽象类、内部类

    一.不需要实例化的原因 看一个示例: package com.zhangguo.chapter5.s1;/**动物园*/ public class Zoo {public static void ma ...

  8. javadoc - Java API 文档生成器(Windows版本)

    文章目录 简介 命令语法结构 Javadoc Doclets 术语 带文档的类 引用类 外部引用类 源文件 源代码文件 包注释文件 概述注释文件 其他未处理文件 生成的文件 基本内容页 交叉参考页 支 ...

  9. java定义属性时用this_(转载)深入Java关键字this的用法的总结

    合它的含义并不完全相同,使用不当还会出现错误, 本文对this的几种用法和出现的问题进行了分析详解. 关键词:类:对象:this:成员变量:方法:构造方法 中,Java语言提供了丰富的类(Class) ...

最新文章

  1. 华御密盾智能防信息泄密系统
  2. twemproxy 简介
  3. spring入门(一)
  4. vscode 好用插件
  5. 对Python匿名函数和@property小小理解,希望对你学习也有帮助
  6. 运行caffe自带的mnist实例详细教
  7. XCoreRedux框架:Android UI组件化与Redux实践
  8. Spark精华问答 | 为什么选择Spark作为流计算引擎?
  9. 卡尔曼滤波推导思路总结
  10. AttachDispatch
  11. admysqlslap压力测试
  12. Unity LitJson的教程
  13. linux申请令牌错误,解决“请求中包含的安全令牌已过期”错误
  14. Win10文件夹Shift+右键菜单添加打开管理员Powershell窗口
  15. 里面可以写名字的爱心代码(html)
  16. Cocos2d-x JSB 自己主动绑定bindings
  17. 关于uni-app的ui库、ui框架、ui组件
  18. Sublime Text3 Python配置
  19. although 与 though 的区别
  20. 贪心算法--电影节(openjudge 4151 )

热门文章

  1. android 单元布局,在Android布局中挖洞
  2. mysql sql 列变成横向_mysql怎么更改纵向变横向排列
  3. 苹果手机闹钟声音大小怎么调_偷偷安利5款让手机体验到爆的app,乐趣满满
  4. Prometheus配合 alertmanager 使用企业微信告警(坑已平!!!)
  5. 教程篇(7.0) 04. FortiGate安全 NAT ❀ Fortinet 网络安全专家 NSE 4
  6. Qt:Windows编程—Qt实现注册表启动项管理
  7. 域名重定向工具 —— SwitchHosts 实用教程
  8. CCID多线程界面-python
  9. vdi转vmdk VirtualBox与VMware硬盘格式转换及使用方法
  10. centos7:glibc:configure: error: no acceptable C compiler found in $PATH