魔方阵

①问题描述

魔方阵是一个古老的智力问题,它要求在一个m×m的矩阵中填入1~m2的数字(m为奇数),使得每一行、每一列、每条对角线的累加和都相等,如图1所示。
































15

8

1

24

17

16

14

7

5

23

22

20

13

6

4

3

21

19

12

10

9

2

25

18

11

图1 五阶魔方阵示例

②基本要求

  • 输入魔方阵的行数m,要求m为奇数,程序对所输入的m作简单的判断,如m有错,能给出适当的提示信息。

  • 实现魔方阵。

  • 输出魔方阵。

③实现提示

本实验使用的数据结构是数组。

解魔方阵问题的方法很多,这里采用如下规则生成魔方阵。

  • 由1开始填数,将1放在第0行的中间位置。

  • 将魔方阵想象成上下、左右相接,每次往左上角走一步,会有下列情况:

    • 左上角超出上方边界,则在最下边相对应的位置填入下一个数字;

    • 左上角超出左边边界,则在最右边相应的位置填入下一个数字;

    • 如果按上述方法找到的位置已填入数据,则在同一列下一行填入下一个数字。

以3×3魔方阵为例,说明其填数过程,如图2所示。

图2
三阶魔方阵的生成过程

由三阶魔方阵的生成过程可知,某一位置(x,y)的左上角的位置是(x-1,y-1),如果x-1≥0,不用调整,否则将其调整为x-1+m;同理,如果y-1≥0,不用调整,否则将其调整为y-1+m。所以,位置(x,y)的左上角的位置可以用求模的方法获得,即:

x=(x-1+m)%m

y=(y-1+m)%m

如果所求的位置已经有数据了,将该数据填入同一列下一行的位置。这里需要注意的是。此时的x和y已经变成之前的上一行上一列了,如果想变回之前位置的下一行同一列,x需要跨越两行,y需要跨越一列,即:

x=(x+2)%m

y=(y+1)%m

④思考

  • 可以考虑使用其他方法生成魔方阵。任何算法都有不同的实现方法,通过采用不同实现方法来重新实现算法,这要比单纯学习算法的效果好得多。

?





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

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

#include<iostream>

#include<string.h>

using
namespace std;

int main()

{

    int
m;//阶数

    int
x , y ;//横坐标,纵坐标

    int
fz;//辅助数

    int
number;//当前要进数组的数字

    cout<<"please input m"<<endl;

    while(cin>>m)

    {

        if(m<=0)//输入判断

        {

            cout<<"input error,please input positive odd"<<endl;

            continue;

        }

        if(m%2==0)//输入判断

        {  

            cout<<"input error,please input positive odd"<<endl;

            continue;

        }

        fz = m;

        int
mofang[m][m];//构建二维数组

        memset(mofang,0,sizeof(mofang));//清零

        mofang[0][m/2] = 1;//把1放到第一行中间

        x = 0 ;

        y = m / 2;

        number = 2;

        while(number <= m * m)//循环条件是进数组的数小于阶数的平方

        {

            if(x-1<0)//上方出界

            {

                if(y-1>=0)//左边没出界,把数插入到左边一行最下面

                {

                    for(int
i = 0 ; i < m ; i ++)

                    {

                        if(mofang[fz-1][y-1]==0)

                            break;

                        else
fz--;

                    }

                    mofang[fz-1][y-1]= number;

                    number ++;

                    x = fz-1;

                    y = y -1;

                    fz = m;

                }

                else//左边出界,把数插入到当前位置的下一行

                {

                    mofang[x+1][y] = number;

                    number ++;

                    x = x + 1;

                    fz = m;

                }

            }

            else
if(y-1 < 0)//左边出界

            {

                for(int
i = 0 ; i < m ; i++)

                {

                    if(mofang[x-1][fz-1]==0)

                        break;

                    else
fz--;

                }

                mofang[x-1][fz-1]= number;

                number ++;

                x = x - 1;

                y = fz - 1;

                fz = m ;

            }

            else
if(mofang[x-1][y-1]!=0)//左上角元素不为0

            {

                mofang[x+1][y] = number ;

                number ++;

                x = x+1;

            }

            else//插入左上角

            {

                mofang[x-1][y-1] = number ;

                x = x -1 ;

                y = y -1;

                number ++;

            }

        }

        for(int
i = 0 ; i < m ; i++)

        {

            for(int
j = 0 ; j < m ; j++)

            {

                cout<<mofang[i][j]<<"       ";

            }

            cout<<endl;

        }

        cout<<endl;

    }

}

  

魔方阵,布布扣,bubuko.com

时间: 2024-10-22 17:20:54

魔方阵的相关文章

奇数阶魔方阵

原题 打印魔方阵,魔方阵是指这样的方针,每一行.每一列以及对角线的和相等.例如三阶魔方阵: 8 1 6 3 5 7 4 9 2 编程打印奇数阶魔方阵. 提示 问题解决的关键是元素的填充,第一个元素1的位置在第一行正中,新的位置应该处于最近插入元素的右上方:但如果右上方的位置超出方针上边界,则新的位置应该取列的最下一个位置:超出右边界则取行的最左的一个位置:若最近插入的元素为n的整数倍,则选下面一行同列上的位置为新的位置. 实现代码 /*******************************

java计算奇数阶魔方阵

一.提出问题 所谓"奇数阶魔方阵"是指n为不小于3的奇数的魔方阵.这类魔方阵的形式多样,这里我们仅讨论其中的一种形式的正规魔方阵.例如:3阶.5阶和7阶的魔方阵如图3 – 4 所示. , , 图3 – 4 3阶5阶和7阶魔方阵 容易知道,这三个魔方阵的魔方常数分别是15.65和175. 现在要求给出:能让计算机自动输出类似图3 – 4 所示的n阶奇数魔方阵的算法,其中n为任意给定的一个不小于3的奇数. 二.简单分析 决定"奇数阶魔方阵"的关键是要按要求决定其方阵中的

SDUST 作业10 Problem D 魔方阵

Description 所谓N阶魔方阵,是一个N*N的方阵,其元素由1到N^2组成,且方阵每行每列以及对角线的元素和相等.如三阶魔方阵: 8 1 6 3 5 7 4 9 2 魔方阵的规律如下: 从1-N*N的 各个数依次如下规则存放: (1) 1在第一行中间一列: (2) 每一个数存放的行比前一个数的行数减一,列数加一(如上的三阶方阵5在4的上一行,后一列): (3) 如果上一个数在第一行,则下一个数在最后一行,列数加一: (4) 如果上一个数在最后一列,则下一个数在第一列,行数减一: (5)

n阶魔方阵

奇数阶魔方阵就是指行列数都是吧n(n>=3 且 n%2 == 1)的魔方阵 奇数阶魔方阵的数字规律 通过对奇数阶魔方阵的分析,其中的数字排列有如下的规律: (1)自然数1出现在第一行的正中间: (2)若填入的数字在第一行(不在第n列),则下一个数字在第n行(最后一行)且列数加1(列数右移一列): (3)若填入的数字在该行的最右侧,则下一个数字就填在上一行的最左侧: (4)一般地,下一个数字在前一个数字的右上方(行数少1,列数加1): (5)若应填的地方已经有数字或在方阵之外,则下一个数字就填在前

输出n阶“魔方阵”

魔方阵:每一行.每一列和对角线之和均相等. 程序如下: 1 #include <stdio.h> 2 #include <stdlib.h> 3 int main() 4 { 5 //输出魔方阵 6 int i,j,k,p,n,a[15][15]; 7 p=1;//用于判断输入的数字是否符合条件 8 while(p==1){ 9 printf("enter n (n=1--15):"); 10 scanf("%d",&n); 11 i

C语言复习---输出魔方阵

一:奇魔方阵 算法: 1.第一个元素放在第一行中间一列 2.下一个元素存放在当前元素的上一行.下一列. 3.如果上一行.下一列已经有内容,则下一个元素的存放位置为当前列的下一行. 在找上一行.下一行或者下一列的时候,必须把这个矩阵看成是回绕的. 算法实现: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <math.h> #define MAXSIZE 100

4N 魔方阵

说明求各行.各列与各对角线的和相等,而这次方阵的维度是4的倍数. 解法先来看看4X4方阵的解法: 简单的说,就是一个从左上由1依序开始填,但遇对角线不填,另一个由左上由16开始填,但只填在对角线,再将两个合起来就是解答了:如果N大于2,则以 4X4为单位画对角线: 至于对角线的位置该如何判断,有两个公式,有兴趣的可以画图印证看看,如下所示:左上至右下: j % 4 == i % 4右上至左下: (j % 4 + i % 4) == 1 #include<stdio.h> #include<

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

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

【4N魔方阵】

/* 4N魔方阵 */ #include<stdio.h> #include<stdlib.h> #define N 8 int main(void){ int i, j; int square[N+1][N+1] = {0}; for(j = 1; j <= N; j++){ for(i = 1; i <= N; i++){ if(j%4 == i%4 || (j%4 + i%4) == 1){ square[i][j] = (N+1-i) * N -j + 1; }