一、幻方按照阶数可分成了三类,奇数阶幻方双偶阶幻方单偶阶幻方

二、奇数阶幻方(劳伯法)

奇数阶幻方最经典的填法是罗伯法。填写的方法是:

把1(或最小的数)放在第一行正中;按以下规律排列剩下的(n×n-1)个数:
(1)每一个数放在前一个数的右上一格;

(2)如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;

(3)如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;

(4)如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在底行且最左列;

(5)如果这个数所要放的格已经有数填入,那么就把它放在前一个数的下一行同一列的格内。

例,用该填法获得的5阶幻方:

17

24

1

8

15

23

5

7

14

16

4

6

13

20

22

10

12

19

21

3

11

18

25

2

9

二、双偶数阶幻方(海尔法)

所谓双偶阶幻方就是当n可以被4整除时的偶阶幻方,即4K阶幻方。在说解法之前我们先说明一个“互补数”定义:就是在n阶幻方中,如果两个数的和等于幻方中最大的数与1的和(即n×n+1),我们称它们为一对互补数。如在三阶幻方中,每一对和为10的数,是一对互补数 ;在四阶幻方中,每一对和为17的数,是一对互补数。

双偶数阶幻方最经典的填法是海尔法。填写的方法是:

以8阶幻方为例:
(1)先把数字按顺序填。然后,按4×4把它分割成4块(如图)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

(2)每个小方阵对角线上的数字(如左上角小方阵部分),换成和它互补的数。

64

2

3

61

60

6

7

57

9

55

54

12

13

51

50

16

17

47

46

20

21

43

42

24

40

26

27

37

36

30

31

33

32

34

35

29

28

38

39

25

41

23

22

44

45

19

18

48

49

15

14

52

53

11

10

56

8

58

59

5

4

62

63

1

三、单偶数阶幻方(斯特拉兹法)

所谓单偶阶幻方就是当n不可以被4整除时的偶阶幻方,即4K+2阶幻方。如(n=6,10,14……)的幻方。

单偶数阶幻方最经典的填法是斯特拉兹法。填写的方法是:

以10阶幻方为例。这时,k=2。
(1)把魔方阵分为A,B,C,D四个象限,这样每一个象限肯定是奇数阶。用罗伯法,依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数。

(2)在A象限的中间行、中间格开始,按自左向右的方向,标出k格。A象限的其它行则标出最左边的k格。将这些格,和C象限相对位置上的数互换位置。

(3)在B象限所有行的中间格,自右向左,标出k-1格。(注:6阶幻方由于k-1=0,所以不用再作B、D象限的数据交换),将这些格,和D象限相对位置上的数互换位置。

以上内容来源:http://www.cnblogs.com/panlijiao/archive/2012/05/11/2496757.html

实现代码如下:

 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>

 #define COL 20
 #define ROW 20

 void deal_argv(int argc, char **argv, int *degree) {
         ) {
                 printf("cmd: ./a.out degree\n");
                 exit(-);
         } else {
                 *degree = atoi(argv[]);
                  || *degree > ) {
                         printf("the degree is between 3 and 20\n");
                         exit(-);
                 }
         }
 }

 void show_array(int (*array)[ROW], int degree) {
         int row, col;
         ; row < degree; row++){
                 ; col < degree; col++)
                         printf("%5d", array[row][col]);
                 printf("\n");
         }
 }

 void init_array(int (*array)[ROW], int size) {
         memset(array, , size);
 }

 void odd_num_magic_square(int degree, int (*array)[ROW], int x, int y, int num) {
         ;
         ;
         ;

         ; element++) {
                 array[col + x][row + y] = element;
                  + degree) % degree + x][(row + ) % degree + y] != ) {
                         col = (col +  + degree) % degree;
                 } else {
                         row = (row + ) % degree;
                         col = (col -  + degree) % degree;
                 }
         }
 }

 void fill_array(int (*array)[ROW], int degree) {
         int row, col;
         ;

         ; col < degree; col++)
                 ; row < degree; row++)
                         array[col][row] = num++;
 }

 void double_magic_square(int degree, int (*array)[ROW]) {
         ;
         ;
         int row, col;

         fill_array(array, degree);
         complement = degree * degree + ;

         ; col < deg; col++) {
                 ; row < deg; row++) {
                         array[col * ][row * ] = complement - array[col * ][row * ];
                         array[col *  + ][row *  + ] = complement - array[col *  + ][row *  + ];
                         array[col *  + ][row *  + ] = complement - array[col *  + ][row *  + ];
                         array[col *  + ][row *  + ] = complement - array[col *  + ][row *  + ];

                         array[col *  + ][row * ] = complement - array[col *  + ][row * ];
                         array[col *  + ][row *  + ] = complement - array[col *  + ][row *  + ];
                         array[col *  + ][row *  + ] = complement - array[col *  + ][row *  + ];
                         array[col * ][row *  + ] = complement - array[col * ][row *  + ];
                 }
         }
 }

 void change_value(int *value_a, int *value_b) {
         int tmp;
         tmp = *value_a;
         *value_a = *value_b;
         *value_b = tmp;
 }

 void single_magic_square(int degree, int (*array)[ROW]) {
         ;
         ;
         int row, col;
         ;

         odd_num_magic_square(deg, array, , , );
         odd_num_magic_square(deg, array, deg, deg, deg * deg + );
         odd_num_magic_square(deg, array, , deg, deg * deg *  + );
         odd_num_magic_square(deg, array, deg, , deg * deg *  + );

         k = (degree - ) / ;
         ; row < k; row++) {
                 ; col < deg; col++) {
                         ) {
                                 change_value(&array[col][deg /  + row], &array[col + deg][deg /  + row]);
                         } else {
                                 change_value(&array[col][row], &array[col + deg][row]);
                         }
                 }
         }

         ; row < k - ; row++) {
                 ; col < deg; col++) {
                         tmp_row = row + deg + deg /  +  - k + ;
                         change_value(&array[col][tmp_row], &array[col + deg][tmp_row]);
                 }
         }

 }

 int main(int argc, char *argv[]) {
         int array[COL][ROW];
         ;

         deal_argv(argc, argv, &degree);

         init_array(array, sizeof(array));
         ) != ) {
                 odd_num_magic_square(degree, array, , , );
                 show_array(array, degree);
         }  == ) {
                 double_magic_square(degree, array);
                 show_array(array, degree);
         } else {
                 single_magic_square(degree, array);
                 show_array(array, degree);
         }

         ;
 }

【C】——幻方算法的更多相关文章

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

    写于2012.10: 本来这是谭浩强那本<C程序设计(第四版)>的一道课后习题,刚开始做得时候去网上找最优的算法,结果发现奇数和双偶数(4的倍数)的情况下算法都比较简单,但是单偶数(2的倍 ...

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

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

  3. acm算法模板(1)

    1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函数 10 1.6 面积 15 1.7 球面 16 1.8 三角形 17 1.9 三维几 ...

  4. Java 实现奇数阶幻方的构造

    一.设计的流程图如下所示 二.Java 语言的代码实现 package MagicSquare; //奇数幻方的实现 public class Magic_Odd { //n 为幻方的阶数 publi ...

  5. 魔方阵算法及C语言实现

    1 魔方阵概念 填充的,每一行.每一列.对角线之和均相等的方阵,阶数n = 3,4,5….魔方阵也称为幻方阵. 例如三阶魔方阵为: 魔方阵有什么的规律呢? 魔方阵分为奇幻方和偶幻方.而偶幻方又分为是4 ...

  6. 【算法】C语言趣味程序设计编程百例精解

    C语言趣味程序设计编程百例精解 C/C++语言经典.实用.趣味程序设计编程百例精解(1)  https://wenku.baidu.com/view/b9f683c08bd63186bcebbc3c. ...

  7. ACM主要算法

    ACM主要算法ACM主要算法介绍 初期篇 一.基本算法(1)枚举(poj1753, poj2965)(2)贪心(poj1328, poj2109, poj2586)(3)递归和分治法(4)递推(5)构 ...

  8. ACM常用算法

    数据结构 栈,队列,链表 哈希表,哈希数组 堆,优先队列 双端队列 可并堆 左偏堆 二叉查找树 Treap 伸展树 并查集 集合计数问题 二分图的识别 平衡二叉树 二叉排序树 线段树 一维线段树 二维 ...

  9. ACM需要掌握算法

    数据结构 栈,队列,链表 哈希表,哈希数组 堆,优先队列 双端队列 可并堆 左偏堆 二叉查找树 Treap 伸展树 并查集 集合计数问题 二分图的识别 平衡二叉树 二叉排序树 线段树 一维线段树 二维 ...

随机推荐

  1. Ubuntu下的生活--安装

    概要 整个安装过程是通过离线包安装,而非在线安装. 目录 JDK安装与配置 Eclipse安装与配置 Apache安装与配置 MySQL的安装 JDK安装与配置 版本:jdk-7u71-linux-i ...

  2. HttpRequest Get Post,WebClient Get

    #region HttpRequestGet public string HttpRequestGet(string url) { return HttpRequestGet(url, WebRequ ...

  3. CSS遮罩——如何在CSS中使用遮罩

    Css遮罩是2008年4月由苹果公司添加到webkit引擎中的.遮罩提供一种基于像素级别的,可以控制元素透明度的能力,类似于png24位或png32位中的alpha透明通道的效果. 图像是由rgb三个 ...

  4. 恢复oracle数据库误删除数据的方法汇总

    学习数据库时,我们只是以学习的态度,考虑如何使用数据库命令语句,并未想过工作中,如果误操作一下,都可能导致无可挽回的损失.当我在工作中真正遇到这些问题时,我开始寻找答案.今天主要以oracle数据库为 ...

  5. Apache2 httpd.conf 配置详解(一)

    常用配置指令说明 ServerRoot:服务器的基础目录,一般来说它将包含conf/和logs/子目录,其它配置文件的相对路径即基于此目录.默认为安装目录,不需更改. 语法:ServerRoot di ...

  6. window.open()被部分浏览器拦截问题

    下面代码一切从简,大家理解即可 一.原因:1.因为在chrome的安全机制里面,非用户触发的window.open方法,是会被拦截的: 二.什么情况下不会被拦截或会被拦截? 1. $('#btn'). ...

  7. Ubuntu18.04安装常用软件

    一.VMwareWorkstation 1.到官网下载VmwareWorkstation,选择Linux版本 2.将下载下来的安装包放到桌面给予x权限,通过命令行进入到桌面的目录sudo ./执行安装 ...

  8. CustomJsonDateDeserializer @JsonDeserialize(using = CustomJsonDateDeserializer.class) Jackson 反序列化Date时遇到的问题 java中json日期属性反序列化

    public class CustomJsonDateDeserializer extends JsonDeserializer<Date> { @Override public Date ...

  9. url组成

  10. ACM__并查集

    并查集是树型的数据结构,处理不想交集合 主要解决查找和合并的问题 步骤: 初始化 把每个点所在的集合初始化为自身 复杂度为O(N) 查找 查找元素所在的集合,即根节点 合并 将两个元素所在的集合合并在 ...