所谓幻方,就是在一个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. loadrunner 更新中......
  2. IBatis.Net学习笔记五--常用的查询方式
  3. python怎么写中文至excel_[ Python爬虫实战 ] python 操作excel以及解决中文报错 - pytorch中文网...
  4. Codeforces 861 A k-rounding 数论
  5. kafka消费者脚本无法启动问题
  6. Python strip()与split()方法
  7. Win 10 没有 Hyper-V 解决方案
  8. Java–cvc-complex-type.4:Attribut ‘version’ must appear on element ‘web-app’
  9. 解决虚拟机桥接模式无法上网的问题
  10. 【交易架构day9】阿里交易系统演进之路
  11. 网站对接支付宝进行支付
  12. 递归学习_组合_全组合排列
  13. 使用Linux Deploy在android手机上部署Ubuntu
  14. Spring基础篇:高级注解编程
  15. 监控文件夹下大小是否有变化
  16. KindEditor上传图片后回调传入文本框和列表框并显示图片
  17. HC05主从蓝牙通信的配置步骤
  18. 亿信华辰:电力行业如何做好数据治理,其核心的3个步骤
  19. 【python 爬虫】反爬的应对(1)
  20. 如何从Arxiv预出版网站导出论文到NoteExpress

热门文章

  1. spark 集群处理后转单机pyspark 或 pands 数据处理 的方法
  2. 数据结构与算法36-联接最大数
  3. mybatis-generator同名表的处理
  4. Google MicroData,谷歌微数据为博客添加评级
  5. 爬FH... ... 爽!
  6. android6.0 cta认证,什么是CTA认证?CTA进网许可认证。
  7. android 锁屏界面 sim卡,注意!手机的这个密码比锁屏密码更重要,赶紧设置!攻略→...
  8. Win10使用Geth搭建本地开发私有链(2021版)
  9. 让你越来越值钱的秘密:目标清单
  10. SQL实际问题——列的替换和汇率打折问题