数据结构 第5章 魔方阵

合集下载

魔方阵算法及C语言实现

魔方阵算法及C语言实现

魔方阵算法及C语言实现1 魔方阵概念魔方阵是指由1,2,3……n2填充的,每一行、每一列、对角线之和均相等的方阵,阶数n = 3,4,5…。

魔方阵也称为幻方阵。

例如三阶魔方阵为:魔方阵有什么的规律呢?魔方阵分为奇幻方和偶幻方。

而偶幻方又分为是4的倍数(如4,8,12……)和不是4的倍数(如6,10,14……)两种。

下面分别进行介绍。

2 奇魔方的算法2.1 奇魔方的规律与算法奇魔方(阶数n = 2 * m + 1,m =1,2,3……)规律如下:1.数字1位于方阵中的第一行中间一列;2.数字a(1 < a ≤ n2)所在行数比a-1行数少1,若a-1的行数为1,则a的行数为n;3.数字a(1 < a ≤ n2)所在列数比a-1列数大1,若a-1的列数为n,则a的列数为1;4.如果a-1是n的倍数,则a(1 < a ≤ n2)的行数比a-1行数大1,列数与a-1相同。

2.2 奇魔方算法的C语言实现1 #include <stdio.h> 2// Author: / 3// N为魔方阶数 4#define N 115 6int main()7{8int a[N][N]; 9int i;10 int col,row;1112 col = (N-1)/2;13 row = 0;1415a[row][col] = 1;1617for(i = 2; i <= N*N; i++)18 {19if((i-1)%N == 0 )20 {21 row++;22 }23else24 {25// if row = 0, then row = N-1, or row = row - 126 row--;27 row = (row+N)%N;2829// if col = N, then col = 0, or col = col + 130 col ++;31 col %= N;32 }33 a[row][col] = i;34 }35for(row = 0;row<N;row++)36 {37for(col = 0;col < N; col ++)38{39 printf("%6d",a[row][col]);40 }41printf("\n");42 }43return0;44 }3 偶魔方的算法偶魔方的情况比较特殊,分为阶数n = 4 * m(m =1,2,3……)的情况和阶数n = 4 * m + 2(m = 1,2,3……)情况两种。

魔方阵

魔方阵

问题3.1、n –魔方阵一、提出问题所谓“n – 魔方阵”是指由1至n 这n 个不同整数构成的魔方阵,其魔方常数为n ( n + 1 ) / 2。

例如,5 – 魔方阵和7 – 魔方阵如图3 – 1所示。

易知,这两个魔方阵的魔方常数分别为15和28。

3215415432432152154354321 ,4321765176543254321762176543654321732176547654321 图3 – 1 5 – 魔方阵和7 – 魔方阵n – 魔方阵的数字排列很有规律,若用人工的方法给出并不困难。

现在要求给出:能让计算机自动输出n (≥ 3)为奇数时形如图3 – 1所示的n – 魔方阵的算法。

二、简单分析n – 魔方阵较我们之后将要讨论的奇、偶数阶魔方阵,要简单许多。

观察后不难发现:1.要填入的n 个数字在阵列的每一行和每一列都要出现且仅出现一次,且各行(列)中的数字顺序相同,这里的顺序是指循环顺序,其中数字1接在数字n 的后面。

2.从阵列的行来看,每一行的第一个数字与它上一行正中间的数字相同。

通过对“n – 魔方阵”的分析,下面几个基本问题必须得到解决:◆ 如何确定阵列第一行各个数字?◆ 在填入其他行的数字时如何保证数字原有的顺序不改变同时每一行的第一个数字正好是其上一行正中间的数字?三、设计准备假设我们要构建的是一个n – 魔方阵,为此定义一个有n 行n 列的二维数组。

1.确定阵列第一行各个数字这里我们处理的方法很简单,即可以利用循环方法顺序地在二维数组第一行中填写1,2,3,…,n 这n 个自然数即可。

2.填入其他行的数字,并保证数字原有的顺序不改变同时每一行的第一个数字正好是其上一行正中间的数字要解决这个问题,需借助一个有n + 1单元的一维数组,并对该数组进行若干次“循环左移”处理。

所谓做一次“循环左移”,即指在一维数组中,将第1个数填入第n + 1个单元,第2个数填入第1个单元,……,第n个数填入第n– 1 个单元,最后再将第n + 1个单元中的数填入第n个单元。

魔阵

魔阵

Page 16
三、单偶阶魔阵的实现
的倍数, 但不是4 的倍数, 注意n 必须大于2 (即n 是2 的倍数, 但不是4 的倍数, 注意n 必须大于2)
单偶阶魔阵的构造基本思想: 单偶阶魔阵的构造基本思想 (1) 将m = n/ 2,则可以分成四个数 , 据段: 据段 1. . m^2 , m^2 + 1. .2*m^2 , 2*m^2 + 1. . 3*m^2 , 3*m^2 + 1. . 4*m^2 ; (2) 采用德拉鲁布算法 分别排出 采用德拉鲁布算法, 分别排出m 阶魔阵A ×m阶魔阵 、B 、C、D 。A 、 阶魔阵 、 B 、C、D 魔阵起始数据分别为 , 、 魔阵起始数据分别为1 m+ 1 , 2*m^2 + 1 , 3*m^2 + 1 ; (3) 将A 、B 、C、D 以图 的形式 、 以图1的形式 合成n× 方阵; 合成 ×n 方阵
图1
Page 17
三、单偶阶魔阵的实现
单偶阶魔阵的构造基本思 想: (4) 将A 、D 方阵中前 m 方阵中前( + 1) / 2 - 1列元素除第 列 列元素除第1 列元素除第 中第( 行不变外, 中第 m + 1) / 2 行不变外 其余分别对应元素交换; 其余分别对应元素交换 (5) 将A 、D 方阵中心元素 交换, 即第( 交换 即第 m+ 1) / 2 行第 ( m + 1) / 2 列; (6) 将B 、C 方阵中后 m 方阵中后( - 1) / 2 - 1 列元素对应交 换。
Page 12
(二)德拉鲁布算法
它是一种构造奇阶方阵的方法, 它是一种构造奇阶方阵的方法,具 体如下: 体如下: 开始,将 放在第一行正中; (1)从1 开始 将1 放在第一行正中; ) (2)接着向右上方移动一格 填入数 )接着向右上方移动一格, 若超出右边(上 界限时, 字, 若超出右边 上 边) 界限时 接至最左边(下边 即行为 列为 下边) 即行为0 列为n 接至最左边 下边 ,即行为 (列为 + 1) 时, 将行改成 (列改为 ; 将行改成n 列改为 列改为1) (3)若右上方已有数字 则向下方一 )若右上方已有数字, 格填数; 格填数 直至数填完n (4)重复 、(3) 直至数填完 ×n )重复(2) 的方阵。 的方阵。

魔方阵

魔方阵

魔方阵,古代又称“纵横图”,是指组成元素为自然数1、2…n的平方的n×n的方阵,其中每个元素值都不相等,且每行、每列以及主、副对角线上各n个元素之和都相等。

如3×3的魔方阵:8 1 63 5 74 9 2魔方阵的排列规律如下:(1)将1放在第一行中间一列;(2)从2开始直到n×n止各数依次按下列规则存放;每一个数存放的行比前一个数的行数减1,列数加1(例如上面的三阶魔方阵,5在4的上一行后一列);(3)如果上一个数的行数为1,则下一个数的行数为n(指最下一行);例如1在第一行,则2应放在最下一行,列数同样加1;(4)当上一个数的列数为n时,下一个数的列数应为1,行数减去1。

例如2在第3行最后一列,则3应放在第二行第一列;(5)如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。

例如按上面的规定,4应该放在第1行第2列,但该位置已经被占据,所以4就放在3的下面;一、魔方阵的简介1.何谓矩阵?矩阵就是由方程组的系数及常数所构成的方阵。

把用在解线性方程组上既方便,又直观。

2.何谓n阶方阵?若一个矩阵是由n个横列与n个纵行所构成,共有个小方格,则称这个方阵是一个n阶方阵。

3.何谓魔方阵?4 9 2 3 5 7 8 1 6定义:由n*n个数字所组成的n阶方阵,具有各对角线,各横列与纵行的数字和都相等的性质,称为魔方阵。

而这个相等的和称为魔术数字。

若填入的数字是从1到n*n,称此种魔方阵为n阶正规魔方阵。

4.最早的魔方阵相传古时为了帮助治水专家大禹统治天下,由水中浮出两只庞大动物背上各负有一图,只有大禹才可指挥其中之由龙马负出的为河图,出自黄河;另一由理龟负出的洛书出自洛河。

洛书5.最早的四阶魔方阵最早的四阶方阵刻在印度一所庙宇石上,年代大约是十一世纪。

古代印度人十分崇拜这种幻方,至今从古神殿的遗址,墓碑上常常还可以发现四阶幻方的遗迹。

数据结构课程设计之奇数魔方阵

数据结构课程设计之奇数魔方阵

长沙理工大学《数据结构》课程设计报告田晓辉学院计算机与通信工程专业计算机科学与技术班级计08-01 学号************学生姓名田晓辉指导教师陈倩诒课程成绩完成日期2010年7月10日课程设计成绩评定学院计算机与通信工程专业计算机科学与技术班级计08-01学号200850080110 学生姓名田晓辉指导教师陈倩诒完成日期2010年7月10日指导教师对学生在课程设计中的评价指导教师对课程设计的评定意见课程设计任务书计算机与通信工程学院计算机科学技术专业用C语言解决魔方阵的问题学生姓名:田晓辉指导老师:陈倩诒摘要本课程设计主要解决设计一个n×n的矩阵中填入1到n2的数字(n为奇数),使得每一行、每一列、每条对角线的累加和都相等的问题。

在课程设计中,系统开发平台为Windows 7,程序设计语言采用Visual C++6.0,程序运行平台为Windows 98/2000/XP/7。

在程序设计中,采用了C 语言结构化程序设计思想和过程设计方法,以功能函数为基本结构,对问题中的要求做出了准确的实现。

程序通过调试运行,初步实现了设计目标。

关键词程序设计;C++6.0;结构化;过程设计;功能函数目录1.引言 (1)1.1课程设计目的 (1)1.2课程设计内容 (1)2.设计思路与方案 (2)3.详细实现 (3)3.1数据结构与数据存储表示 (3)3.2功能函数 (3)3.3函数逻辑功能调用图 (5)3.4本程序执行流程图 (6)4.运行环境与结果 (7)4.1程序运行环境 (7)4.2程序运行结果 (7)5.结束语 (9)参考文献 (10)附录源程序代码 (11)1 引言本课程设计主要解决设计一个n×n的方阵中填入1到n2(n为奇数)的数字,使得每一行、每一列、每条对角线上各个数字累加的和都相等的问题。

1.1 课程设计目的通过这次课程设计进一步了解了二维数组的使用方法和一些基本的设计思路。

数据结构实验报告-魔方阵

数据结构实验报告-魔方阵

数据结构与程序设计实验实验报告
哈尔滨工程大学
实验报告三
c. 如果按上述方法找到的位置已填入数据,则在同一列下一行填入下一个数字。

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

三阶魔方阵的生成过程
由三阶魔方阵的生成过程可知,某一位置(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
printf("%d\t",a[i][j]);
printf("\n");
}
四、界面设计
程序需要获取魔方阵的阶数(包括错误判断),输出结果,均在执行过程中给出提示。

五、运行测试与分析
1. 获取阶数并给出错误提示
2. 获取正确阶数,并输出结果
六、实验收获与思考
本次实验采用的数据结构为二维数组,在使用过程中巩固了学习的知识,在用C语言实现魔方阵算法时对C语言的使用更加熟悉。

七、附录(原程序)。

数据结构 陈雁 第5章 自测练习题参考答案

数据结构 陈雁 第5章  自测练习题参考答案

第5章自测练习题参考答案1.设一个有向图G =(V,E),其中V={ v1,v2,v3,v4 },E={<v1,v4>,<v2,v1>,<v2,v3>,<v4,v1>,<v4,v2>}。

请画出该有向图,并求出每个顶点的入度与出度,画出相应的邻接矩阵、邻接表和逆邻接表。

解:有向图:V1入度2,出度1,v2入度1,出度2,v3入度1,出度0,v4入度1,出度2邻接阵:邻接表:逆邻接表:2.分别求出题图5-1从v 2出发按深度优先搜索和广度优先搜索算法遍历得到的顶点序列(假设图的存储结构采用邻接矩阵表示)。

解 :广度优先序列是:v2,v1,v3,v6,v4,v5 深度优先序列是:v2,v1,v3,v4,v5,v63.已知一个有向图的邻接表如题图5-2所示,求出根据深度优先搜索算法从顶点v 1出发遍历得到的顶点序列。

解 :深度优先序列是:v1,v3,v4,v5,v2 广度优先序列是:v1,v3,v2,v4,v54.分别用普里姆和克鲁斯卡尔算法构造题图5-3所示网络的最小生成树。

解 :普里姆算法: (v1,v3) (v3,v4)(v4,v5)(v4,v2) 或 (v5,v2)克鲁斯卡尔算法: (v4,v5)(v2,v4) 或 (v2,v5) (v1,v3) (v3,v4)5.求出题图5-4从顶点v 1到其它各顶点之间的最短路径。

解:(v1-v3 ) 5 (v1-v3-v6) 15 (v1-v3-v6-v4) 19 (v1-v2) 20 (v1-v3-v6-v5) 256.画出题图5-5所示的AOV网所有可能的拓扑有序序列。

并指出应用拓扑排序算法求得的是那一个序列(若选用邻接表作存储结构)?解:(1)所有可能的拓扑有序序列:v1,v4,v2,v5,v3 ,v6v1,v4,v2,v3,v5, v6v1,v4,v5,v2,v3, v6v4,v1,v2,v5,v3, v6v4,v1,v2,v3,v5, v6v4,v1,v5,v2,v3, v6v4,v5,v1,v2,v3, v6(2)根据邻接表,应用拓扑排序算法求得的序列是:v4,v5,v1,v2,v3 v6。

魔方阵

魔方阵

C语言程序求魔方阵如下:(求奇数幻方)代码一:#include <stdio.h>#define N 16 //这里可以修改N的值int main(){int a[N][N]={0},i,j,k,p,m,n;p=1;while(p==1){printf("Enter n(1~%d): ",N-1);/*可以输入小于等于N-1的整数*/ scanf("%d",&n);if((n!=0)&&(n<N)&&(n%2!=0)) p=0;}i=n+1;j=n/2+1; /*建立魔方阵*/a[1][j]=1;for(k=2;k<=n*n;k++){i=i-1;j=j+1;if((i<1)&&(j>n)){i=i+2;j=j-1;}else{if(i<1) i=n;if(j>n) j=1;}if(a[i][j]==0) a[i][j]=k;else{i=i+2;j=j-1;a[i][j]=k;}}for(i=1;i<=n;i++)/*输出魔方阵*/{for(j=1;j<=n;j++)printf("%4d",a[i][j]);}printf("\n");}代码二:(相对于代码一条理更清晰,更简单、更容易理解)将1~n的平方这几个数构成一个n阶魔方阵。

算法:依以下法则,你可以很快的写出奇数阶幻方!当然,这种写法只是其中一个答案,而不是唯一答案。

1)将1填入第一行中间;2)将每个数填在前一个数的右上方。

3)若该位置超出最上行,则改填在最下行的对应位置;4)若该位置超出最右列,则该填在最左列的对应行位置;5)若某元素填在第一行最右列,下一个数填在该数同列的下一行;6)若某数已填好,但其右上角已填了其他数据,则下一个数填在该数同列的下一行位置。

数据结构 魔方阵

数据结构 魔方阵

【完成题目2】魔方阵【问题描述】魔方阵是一个古老的智力问题,它要求在一个m*n的矩阵中填入1~m2的数字(m为奇数),使得每一行、每一列、每条对角线的累加和都相等,如下图所示:(a)三阶魔方阵(b)五阶魔方阵【基本要求】1.输入魔方阵的行数m,要求m为奇数,程序对所输入的m作简单的判断,如m有错,能给出提示信息;2.实现魔方阵;3.输出魔方阵。

【算法设计】首先,输入一个数字m(0<m<100),则输出对应的m阶魔方阵,并输出每一行、每一列、每条对角线上各个数字累加和。

若输入数字m超出要求范围或数字m为偶数或数字m<0,则提醒用户输入错误,需重新输入m。

使用多维数组输出魔方阵。

输入形式:数字m(0<m<100)。

输出形式:以矩阵形式输出n(0<m<100)阶奇数魔方阵;【源代码】#include <iostream>using namespace std;int main(int argc, char* argv[]){int i,j,m,k;//i:行,j:列,m:阶数,k:矩阵int a[100][100];cout<<"请输入一个奇数m (0<m<100):";loop1: cin>>m; //loop:循环if(m%2==0||m<0||m>=100){cout<<"输入错误!请重新输入一个奇数n (0<m<100):";goto loop1;}i=0;j=m/2;for(k=1;k<=m*m;k++){a[i][j]=k;if(k%m==0)i++;//行数加1else{i=(i==0)?m-1:i-1;j=(j==m-1)?0:j+1;}}for(i=0;i<m;i++){for(j=0;j<m;j++){cout<<a[i][j]<<" ";}cout<<endl;}return 0;}【结果截图】【收获及体会】本次课程设计我选择了一个古老的书序趣味问题——魔方阵,通过我的努力与探索,终于解决了奇数阶魔方阵的算法——左上斜行法。

实验报告魔方阵程序(3篇)

实验报告魔方阵程序(3篇)

第1篇一、实验目的1. 熟悉Python编程语言的基本语法和常用数据结构。

2. 学习使用嵌套循环实现复杂数据结构的构建。

3. 掌握随机数生成和排序算法在程序中的应用。

4. 提高编程能力和问题解决能力。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容本实验旨在设计一个魔方阵程序,实现以下功能:1. 生成一个nn的魔方阵。

2. 魔方阵中,每一行的数字之和等于n。

3. 魔方阵中,每一列的数字之和等于n。

4. 魔方阵中,对角线的数字之和等于n。

四、实验步骤1. 导入所需的库```pythonimport random```2. 定义一个函数,用于生成nn的魔方阵```pythondef generate_magic_square(n):初始化一个nn的二维数组,用于存储魔方阵的数字 magic_square = [[0] n for _ in range(n)]num = 1 用于存储当前要填充的数字i, j = 0, n // 2 初始化起始位置while num <= n n:将数字num填充到当前位置magic_square[i][j] = numnum += 1判断下一个位置new_i, new_j = (i - 1) % n, (j + 1) % n 如果当前位置已被填充,则移动到新位置if magic_square[new_i][new_j] != 0:i, j = (i + 1) % n, jelse:i, j = new_i, new_jreturn magic_square```3. 定义一个函数,用于检查魔方阵是否正确```pythondef check_magic_square(magic_square, n):检查每一行的数字之和是否等于nfor i in range(n):if sum(magic_square[i]) != n:return False检查每一列的数字之和是否等于nfor j in range(n):if sum(magic_square[i][j] for i in range(n)) != n:return False检查对角线的数字之和是否等于nif sum(magic_square[i][i] for i in range(n)) != n or sum(magic_square[i][n - i - 1] for i in range(n)) != n:return Falsereturn True```4. 主函数```pythondef main():n = int(input("请输入魔方阵的阶数:"))magic_square = generate_magic_square(n)if check_magic_square(magic_square, n):for row in magic_square:print(' '.join(map(str, row)))else:print("生成的魔方阵不正确!")```5. 运行程序```pythonif __name__ == "__main__":main()```五、实验结果当输入阶数n为5时,程序输出如下魔方阵:```1 2 3 4 512 13 14 15 1011 16 17 18 196 7 8 9 205 4 3 2 1```六、实验总结通过本次实验,我们成功设计并实现了一个魔方阵程序。

中南大学数据结构与算法第5章数组和广义表课后作业答案

中南大学数据结构与算法第5章数组和广义表课后作业答案

第5章数组与广义表习题练习答案5.1请按行及按列优先顺序列出四维数组A2*3*2*3的所有元素在内存中的存储次序,开始结点为a0000。

解:按行优先的顺序排列时,先变化右边的下标,也就是右到左依次变化,这个四维数组的排列是这样的:(将这个排列分行写出以便与阅读,只要按从左到右的顺序存放就是在内存中的排列位置) a0000a0001a0002a0010a0011a0012a0100a0101a0102a0110a0111a0112a0200a0201a0202a0210a0211a0212a1000a1001a1002a1010a1011a1012a1100a1101a1102a1110a1111a1112a1200a1201a1202a1210a1211a1212按列优先的顺序排列恰恰相反,变化最快的是左边的下标,然后向右变化,所以这个四维数组的排列将是这样的,(这里为了便于阅读,也将其书写为分行形式):a0000a1000a0100a1100a0200a1200a0010a1010a0110a1110a0210a1210a0001a1001a0101a1101a0201a1201a0011a1011a0111a1111a0211a1211a0002a1002a0102a1102a0202a1202a0012a1012a0112a1112a0212a02125.2 给出C语言的三维数组地址计算公式。

解:因为C语言的数组下标下界是0,所以Loc(A mnp)=Loc(A000)+((i*n*p)+k)*d其中Amnp表示三维数组。

Loc(A000)表示数组起始位置。

i、j、k表示当前元素的下标,d表示每个元素所占单元数。

5.3设有三对角矩阵A n*n,将其三条对角线上的元素逐行地存储到向量B[0...3n-3]中,使得B[k]=a ij,求:(1)用i , j 表示k的下标变换公式。

(2)用k 表示i,j 的下标变换公式。

c语言魔方阵课程设计

c语言魔方阵课程设计

c语言魔方阵课程设计一、教学目标本课程的目标是让学生掌握C语言编程基础,学会使用C语言编写魔方阵,并培养学生的逻辑思维能力和编程实践能力。

具体目标如下:1.知识目标:–掌握C语言的基本语法和数据类型。

–学会使用C语言进行条件判断和循环控制。

–理解函数的定义和调用。

–学习魔方阵的生成原理和算法。

2.技能目标:–能够使用C语言编写简单的程序。

–学会使用C语言编写魔方阵程序。

–培养学生的编程实践能力和问题解决能力。

3.情感态度价值观目标:–培养学生的学习兴趣和主动性。

–培养学生的团队合作意识和沟通能力。

–培养学生的创新思维和自我探索精神。

二、教学内容本课程的教学内容主要包括C语言的基本语法和数据类型、条件判断和循环控制、函数的定义和调用,以及魔方阵的生成原理和算法。

具体安排如下:1.C语言的基本语法和数据类型:介绍C语言的基本语法规则,包括变量声明、数据类型、运算符、表达式等。

2.条件判断和循环控制:介绍条件语句(if-else)和循环语句(for、while)的使用,以及它们的嵌套和应用。

3.函数的定义和调用:介绍函数的定义、声明和调用方式,以及函数的参数传递和返回值。

4.魔方阵的生成原理和算法:介绍魔方阵的定义和生成原理,以及常用的魔方阵生成算法。

三、教学方法本课程的教学方法采用讲授法、案例分析法和实验法相结合的方式。

具体方法如下:1.讲授法:通过教师的讲解和演示,让学生掌握C语言的基本语法和数据类型、条件判断和循环控制、函数的定义和调用等知识。

2.案例分析法:通过分析具体的魔方阵案例,让学生理解魔方阵的生成原理和算法,并学会使用C语言编写魔方阵程序。

3.实验法:通过编程实验,让学生亲自动手编写程序,培养学生的编程实践能力和问题解决能力。

四、教学资源本课程的教学资源包括教材、参考书、多媒体资料和实验设备。

具体资源如下:1.教材:选用《C程序设计语言》作为主要教材,介绍C语言的基本语法和数据类型、条件判断和循环控制、函数的定义和调用等内容。

魔方阵 C语言

魔方阵 C语言

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

二、奇数阶幻方(劳伯法)奇数阶幻方最经典的填法是罗伯法。

填写的方法是:把1(或最小的数)放在第一行正中;按以下规律排列剩下的(n×n-1)个数:(1)每一个数放在前一个数的右上一格;(2)如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;(3)如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;(4)如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在底行且最左列;(5)如果这个数所要放的格已经有数填入,那么就把它放在前一个数的下一行同一列的格内。

例,用该填法获得的5阶幻方:三、单偶数阶幻方(斯特拉兹法)所谓单偶阶幻方就是当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象限相对位置上的数互换位置。

四、源代码如下,已加详细注释#include<stdio.h>#include<stdlib.h>int array[15][15];intinit(int degree) //初始化{inti;int j;for(i=0; i<=degree+1; i++)for(j=0; j<=degree+1; j++)array[i][j] = 0;return 0;}inttest_print(int x, int y, int w, int h) //测试用的,输出以(x,y)为原点,宽为w,高为h,这个区域的数值{inti;int j;for(i=y; i<=y+h-1; i++){for(j=x; j<=x+w-1; j++){printf("%2d ",array[i][j]);}printf("\n");}return 0;}intlao_bo_er(int degree, int x, int y, intnum) //劳伯法{inti;int j;int k;i = y;j = degree/2 + x;for(k=num; k<=num+degree*degree-1; k++){array[i][j] = k;if((k-num+1)%degree == 0){ //如果这个数所要放的格已经有数填入i = (i-y+1)%degree+y;}else{ //每一个数放在前一个数的右上一格i = (i-y-1+degree)%degree+y;j = (j-x+1)%degree+x;}}return 0;}intseq_range(int degree) //把数字按顺序填{inti;int j;intnum;num = 1;for(i=1; i<=degree; i++){for(j=1; j<=degree; j++){array[i][j] = num++;}}return 0;}intsi_te_la_zi(int degree, int x, int y, intnum) //斯特拉兹法{intdeg;int k;int temp;inti;int j;deg = degree/2;lao_bo_er(deg, x, y, num); //用罗伯法,依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数lao_bo_er(deg, x+deg, y, num+2*deg*deg);lao_bo_er(deg, x, y+deg, num+3*deg*deg);lao_bo_er(deg, x+deg, y+deg, num+deg*deg);k = (degree-2)/4;for(i=1; i<=deg; i++){ //A象限和C象限对换数据for(j=1; j<=k; j++){temp = array[i][j];array[i][j] = array[i+deg][j];array[i+deg][j]=temp;}for(j=deg+deg/2+1; j>=deg+deg/2-k+3; j--){temp = array[i][j];array[i][j] = array[i+deg][j];array[i+deg][j]=temp;}}for(i=j=1; j<=deg/2+k; j++){ //B象限和D象限对换数据temp = array[i+deg/2][j];array[i+deg/2][j] = array[i+deg+deg/2][j];array[i+deg+deg/2][j]=temp;}return 0;}inthai_er_fa(int degree) //海尔法{inti;int j;int complement;intdeg;seq_range(degree);complement = degree*degree+1;deg = degree/4;for(i=0; i<deg; i++){for(j=0; j<deg; j++){ //对角线上的数字换成和它互补的数array[i*4+1][j*4+1] = complement -array[i*4+1][j*4+1];array[i*4+1][j*4+4] = complement -array[i*4+1][j*4+4];array[i*4+4][j*4+1] = complement -array[i*4+4][j*4+1];array[i*4+4][j*4+4] = complement -array[i*4+4][j*4+4];array[i*4+2][j*4+2] = complement -array[i*4+2][j*4+2];array[i*4+2][j*4+3] = complement -array[i*4+2][j*4+3];array[i*4+3][j*4+2] = complement -array[i*4+3][j*4+2];array[i*4+3][j*4+3] = complement -array[i*4+3][j*4+3];}}return 0;}int main(){int degree;printf("please input the degree\n");scanf("%d",&degree);init(degree);if(degree%2 == 1){ //奇数阶幻方lao_bo_er(degree,1,1,1);test_print(1,1,degree,degree);}else if(degree%4 == 2){ //双偶阶幻方si_te_la_zi(degree, 1, 1, 1);test_print(1,1,degree,degree);}else{ //单偶阶幻方hai_er_fa(degree);test_print(1,1,degree,degree);}return 0;}。

C++面向对象编程:魔方阵习题示例

C++面向对象编程:魔方阵习题示例

所谓魔方阵,指的是1~n*n共n*n个自然数,排列成nXn的方阵,使得该方阵的每行、每列、对角线元素之和相等,并为只与n有关的常数,该常数为(1/2)nX(nXn+1)。

假定阵列的行列下标都从1开始,则魔方阵的生成方法如下:1.在第1行中间置1;2.假定当前元素的下标为(i,j),则对其余的2~n*n个数,基本的放置位置为当前位置的右上方,即下标为(i-1,j+1)。

与此同时,若当前的数是n的倍数,则放在当前位置的正下方,即下标为(i+1,j);若i-1小于1,则将这个数放在本列的最下端;若j+1大于n,则将这个数放在本行的最左端。

#include "stdafx.h"#include <malloc.h>#include <stdlib.h>void Array(int n);void main(){int n;printf("Set n,please:\n");scanf("%d",&n);Array(n);system("PAUSE");}void Array(int n){int i, j, no, num, max;int *mtrx;if (n % 2 == 0){n = n + 1;}max = n * n;/*C数组时基于0的*/mtrx = (int*)malloc(max);mtrx[n / 2] = 1;i = 0;j = n / 2;for (num = 2; num <= max; num ++){i = i - 1;j = j + 1;if ((num - 1) % n == 0){i = i + 2;j = j - 1;}if (i < 0){i = n - 1;}if(j > n - 1){j = 0;}no = i * n + j;mtrx[no] = num;}/*显示魔阵的元素*/printf("The charming matrix is :"); no = 0;for (i = 0; i < n; i ++){printf("\n");for(j = 0; j < n; j ++){printf("%3d",mtrx[no]);no ++;}}}。

数据结构课程设计奇偶魔方阵

数据结构课程设计奇偶魔方阵

1 引言本课程设计主要解决一个古老的智力问题。

它要求在一个n*n矩阵中填入1到n*n 数字(由于只是奇数的话,过于简单,因此,我不限定n),使得每一行、每一列、每条对角线的累加和都相等。

输入x,要求打印由自然数1到n*n构成的魔方阵。

1.1课程设计目的本课程设计是建立在数据结构这门课程基础上,数据结构是计算机及相关专业基础课,也是计算机及相关专业考研和水平等级考试的必考科目。

它所讨论的知识内容和提倡的技术方法,无论对进一步学习计算机领域的其他课程,还是对从事软件工程的开发,都有着不可代替的作用。

为了适应21世纪人才培养的需要,理论知识与实践训练相结合,培养动手能力,是课程设计的最终目的,通过实际项目的分析、设计、编码、测试等工作,掌握用C++语言来开发和维护软件;按要求编写课程设计报告书,能正确编写分析、设计、编码、测试等技术文档。

1.2课程设计内容就本课程设计而言,程序设计的结构是为了体现数据结构的思想与内容,在正文第二节设计思路与方案中算法设计的描述,通过自然语言来详尽地梗概魔方阵的实现过程,同时,会在第三节中用程序设计语言(C++语言)[1] [2] [3]书写的算法语句和解释来详细描述魔方阵实现进程,算法描述后是运行环境与运行结果,通过调试来完善算法,达到最终要求。

最后是本人的结束语,其中有本课程设计的技术总结,并附带参考文献与程序设计的源代码,便于读者查看。

2 设计思路与方案。

2.1 设计思路(1)当n为奇数时,即n=2*m+1时,算法为:首先,把1填在第一行的正中间。

其次,若数k填在第i行第j列的格子中,那么k+1应填在它的左上方,即i-1,j-1;如果左上方没有格子,若i-1=0,那么k+1填在第n行第j-1列的格子中;若j-1=0,那么k+1填在第i-1行第n列的格子中;若i-1=0,j-1=0,那么k+1填在第n行第n列的格子中。

再次,若按上述方法找到的格子都已经填过了数,那么,数k+1填在第k个数的正下方。

魔方矩阵实验报告

魔方矩阵实验报告

一、实验目的1. 理解魔方矩阵的概念和性质。

2. 掌握构造不同大小的魔方矩阵的方法。

3. 通过编程实现魔方矩阵的生成。

4. 分析魔方矩阵在不同维度上的应用。

二、实验原理魔方矩阵,又称幻方矩阵,是一种具有特殊性质的方阵。

在这种矩阵中,每一行、每一列以及对角线上的元素之和都相等。

此外,矩阵中的每个元素都是唯一的,不重复。

构造魔方矩阵的方法有多种,其中最经典的是Siamese方法(又称Siedlecki方法)。

该方法适用于构造3x3以上的魔方矩阵。

三、实验内容1. 3x3魔方矩阵的构造以3x3魔方矩阵为例,我们采用Siamese方法进行构造。

(1)首先,将数字1-9填入3x3矩阵的第一行,使得每个数字只出现一次。

(2)然后,将数字1-9填入第二行,每个数字移动两列,若移动到行首,则从行尾开始。

(3)最后,将数字1-9填入第三行,每个数字移动两列,若移动到行首,则从行尾开始。

经过以上步骤,我们得到一个3x3魔方矩阵。

2. 4x4魔方矩阵的构造以4x4魔方矩阵为例,我们采用Siamese方法进行构造。

(1)首先,将数字1-16填入4x4矩阵的第一行,使得每个数字只出现一次。

(2)然后,将数字1-16填入第二行,每个数字移动两列,若移动到行首,则从行尾开始。

(3)接下来,将数字1-16填入第三行,每个数字移动两列,若移动到行首,则从行尾开始。

(4)最后,将数字1-16填入第四行,每个数字移动两列,若移动到行首,则从行尾开始。

经过以上步骤,我们得到一个4x4魔方矩阵。

3. 编程实现魔方矩阵的生成使用Python编程语言,我们可以编写一个函数来生成任意大小的魔方矩阵。

```pythondef generate_magic_square(n):# 初始化矩阵magic_square = [[0] n for _ in range(n)]num = 1# 填充矩阵i, j = 0, n // 2while num <= n n:magic_square[i][j] = numnum += 1new_i, new_j = (i - 1) % n, (j + 1) % nif magic_square[new_i][new_j]:i += 1else:i, j = new_i, new_jreturn magic_square# 生成3x3魔方矩阵magic_square_3x3 = generate_magic_square(3)# 生成4x4魔方矩阵magic_square_4x4 = generate_magic_square(4)```4. 分析魔方矩阵在不同维度上的应用魔方矩阵在数学、计算机科学、密码学等领域有着广泛的应用。

魔方阵

魔方阵

第五章数据结构实验报告实验名称:魔方阵实验类型:设计性实验1.问题描述①问题描述魔方阵是一个古老的智力问题,它要求在一个m×m的矩阵中填入1~m2的数字(m为奇数),使得每一行、每一列、每条对角线的累加和都相等,如图1所示。

2.数据结构设计魔方阵形式上可用二维数组保存并表示,所以构造魔方阵数组如下:int cube[MAX][MAX]。

MAX为全局静态变量,控制魔方阵最大容量。

3.算法设计系统规定的功能包括输入魔方阵的行数并进行判断,实现魔方阵以及输出魔方阵。

魔方阵行数的输入及判断:while(1){memset(cube,0,sizeof(cube)); //魔方阵的初始化。

cout << "Input the size(m) of the cube :{Attention !m%2!=0 , end with m = -1} "<<endl; //魔方阵输入提示。

cin >>m;if(m<=1||m%2==0) //判断魔方阵大小是否为偶数{ //及魔方阵大小是否合法。

if(m == -1) exit(0); //若输入-1则跳出程序cout << "Size Error!"<<endl;cout << endl;continue;}else...魔方阵的实现:int x = 0, y = m/2; //初始化设置坐标,锁定方阵中为1的位置。

bool f= false; //设置判断,防止重复为同一位置赋值。

for(int i = x, j = y ,t = 1; t<=m*m; t++,i--,j--)//循环以1开始,至出现方阵大小的{ //平方即m*m时停止;if(i<0) i+=m; //边界修正。

if(j<0) j+=m;if(f&&i==x&&j==y) //如果判断为已赋值且回到初始位{ //置,则进行坐标修复进行下一位置。

C语言魔方阵的三种实现方法

C语言魔方阵的三种实现方法

C语⾔魔⽅阵的三种实现⽅法⽬录魔⽅阵:1.奇数阶魔⽅阵2.偶数阶魔⽅阵(n=4K)3.偶数阶魔⽅阵(n=4K+2)魔⽅阵:把1到n*n排成n⾏n列⽅阵,使⽅阵中的每⼀⾏、每⼀列以及对⾓线上的数之和都相同,即为n阶魔⽅阵。

根据魔⽅阵的规律,我将它分为三种情况。

1.奇数阶魔⽅阵规律:第⼀个数放在第⼀⾏的中间,下⼀个数放在上⼀个数的上⼀⾏下⼀列,若该位置已经有了数字即放在上个数的下⾯⼀⾏的相同列⽤C语⾔编程如下:⽰例:n=5;#include<stdio.h>#include<stdlib.h>#include<assert.h>void Magic1(){#define ROW 5#define COL ROWassert(ROW % 2 != 0); //判断n是否为奇数int arr[ROW][COL] = { 0 }; //定义⼆维数组int currow = 0;int curcol = COL / 2;arr[currow][curcol] = 1;for (int i = 2; i <= ROW * COL; i++){if (arr[(currow - 1 + ROW) % ROW][(curcol + 1) % COL] == 0) //按照规律赋值{currow = (currow - 1 + ROW) % ROW;curcol = (curcol + 1) % COL;}else{currow = (currow + 1) % ROW;}arr[currow][curcol] = i;}for (int i = 0; i < ROW; i++) //打印魔⽅阵{for (int j = 0; j < COL; j++){printf("%-3d", arr[i][j]);}printf("\n");}}int main(){Magic1();return 0;}结果:2.偶数阶魔⽅阵(n=4K)规律:按数字从⼩到⼤,即1,2,3……n顺序对魔⽅阵从左到右,从上到下进⾏填充;将魔⽅阵分成若⼲个4×4⼦⽅阵(如:8阶魔⽅阵可分成四个4×4⼦⽅阵),将⼦⽅阵对⾓线上的元素取出;将取出的元素按从⼤到⼩的顺序依次填充到n×n⽅阵的空缺处。

输出魔方阵。魔方阵是指这样的方阵,它的每一行,每一列和对角线之和均相等。

输出魔方阵。魔方阵是指这样的方阵,它的每一行,每一列和对角线之和均相等。

输出魔方阵。

魔方阵是指这样的方阵,它的每一行,每一列和对角线之和均相等。

20.输出魔方阵。

魔方阵是指这样的方阵,它的每一行,每一列和对角线之和均相等。

/*输出魔方阵。

魔方阵是指这样的方阵,它的每一行,*每一列和对角线之和均相等。

*/#include <stdio.h>/*声明常量SIZE值,限制数组的大小*/#define SIZE 16/*声明函数input按魔方阵的要求读取数组*/void input(int[][SIZE],int);main(){/*将二维数组a初始化为0,x,y用于控制行与列,*n存储要输出的数组长与宽*/int a[SIZE][SIZE]={0},x,y,n;printf("enter n(1 to %d):",SIZE-1);scanf("%d",&n);/*应用函数读取数组*/input(a,n);/*按行与列要求输出数组*/for(x=1;x<=n;x++){for(y=1;y<=n;y++)printf("%4d",a[x][y]);printf("\n");}return(0);}/*定义函数input按魔方阵的要求读取数组*/ void input(int a[][SIZE],int n){int x,y,i;/*按要求决定数组的第一个元素*/y=(n+1)/2;x=1;a[x][y]=1;/*按要求将2到n平方的值依次赋予数组元素*/ for(i=2;i<=n*n;i++){x-=1;y+=1;if((a[x][y]!=0)||(x==0&&y==n+1)){y-=1;x+=2;if(x>n)x=1;}if(x<1)x=n;if(y>n)y=1;a[x][y]=i;}}运行效果如图:。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构
实验报告第五章
实验名称:魔方阵
实验类型:设计性实验
班级:
学号:
姓名:
实验日期:2014年6月7日
1.问题描述
魔方阵是一个古老的智力问题,它要求在一个m×m的矩阵中填入1~m2的数字(m为奇数),使得每一行、每一列、每条对角线的累加和都相等,如图1所示。

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

●实现魔方阵。

●输出魔方阵。

2.数据结构设计
这个问题的数据结构使用数组就可以解决。

3.算法设计
●由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
4.运行、测试与分析
(1)程序开始运行并输入。

(2)输出结果。

(3)容错检验。

(4)测试其他数据。

5.实验收获及思考
遇到的问题:
输出结果不正确。

解决办法:
因为程序较短,通过肉眼观察程序,发现是数组下标表示错误,一时大意把n维数组的下标范围误认为从1到n,经过修改后,输出结果正常。

实验的收获:
这次试验体会到了解决问题时算法的重要性,一个良好的解法可以使程序大大简化。

附录:
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
int m;//m是魔方阵的行数
int n=1;//用来递增给每个位置赋值
int x,y;//i是行数,j是列数 cout<<"输入魔方阵的行数:";
while(1)
{
cout<<"输入魔方阵的行数。

";
cin>>m;
if(!(m>=1&&m%2==1)) //检验行数是否是奇数{cout<<"输入有误!请输入正奇数。

"; exit(-2);} int shuzu[m][m]; //建立魔方阵,并且全部元素为0 for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
shuzu[i][j]=0;
}
}
x=0;
y=(m-1)/2;
shuzu[x][y]=n++;
while(1)
{
x=(x-1+m)%m; //左上移动
y=(y-1+m)%m;
if(!(shuzu[x][y]==0))
{
x=(x+2)%m;
y=(y+1)%m;
}
shuzu[x][y]=n++;
if(n==m*m+1) break;
}
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
cout<<shuzu[i][j]<<" ";
}
cout<<endl;
}
}
return 0;
}。

相关文档
最新文档