第一篇:魔方阵 实验报告
<< 魔方阵 >>实验报告
一. 实验目的
1.设计数据结构;
2.设计算法完成任意n阶魔方阵的填数; 3.分析算法的时间复杂度。
二. 实验内容
魔方阵,又叫幻方阵,在我国古代称为“纵横图”。它是在一个n*n的矩阵中填入1到n*n的数字(n为奇数),使得每一行,每一列,每条对角线的累加和都相等。
三. 程序代码
源程序:
#include
int p=0, q=(n-1)/2;
a[0][q]=1;
//在第0行的中间位置填1
for(int i=2;i<=n*n;i++)
{
p=(p-1+n)% n;
//求i所在行号
q=(q-1+n)% n;
//求i所在列号
if(a[p][q]>0){
p=(p+2)%n;q=(q+1)%n;
//这两句进行了修改,否者得不到正确的答案,切记切记!!
}//如果位置(p, q)已经有数,填入同一列下一行
a[p][q]=i;
}
for(p=0;p {for(q=0;q cout< cout<<'n';} } void main(){ int n;cout<<“请输入魔方矩阵的阶数n=(n为奇数且<=9):”;cin>>n;cout<<“魔方阵的排列结果为:n”; Square(n);} 四.结果与心得体会 1.程序的测试结果是什么? 答:n=3时 n=5时 2.在调试的过程中遇到了什么问题,是如何解决的? 答:在调试的过程中遇到了以下几个问题: 1.Square函数的形式参数不可以是(int a[][], int n),因为程序是在编译时就会为数组分配内存,而那样的形式参数是不合理的。在调试程序的过程中,我反复试了好多次,也证明了那是错的。解决方法:直接将Square函数的形参设为(int n),改在在其函数内定义数组a[9][9],这样就能将问题很好的解决。 2.在书中提供的Square函数里面,有一个语句是这样的if(a[p][q]>0) p=(p+1)%n;,这个语句是错的。之所以会有这样的错误,是由于错误的理解了“如果位置(p, q)已经有数,填入同一列下一行”这一句的意思,这句的意思是填入原数的下面,而不是即将填入的那个数但又已填入数的那个数的下面。 解决方法:将该语句改成: if(a[p][q]>0) { p=(p+2)%n;q=(q+1)%n; },这样就可以了。 3.由于数组a[][]是在Square函数中定义的,因此将数组数据输出的语句就只能放在Square函数中实现。 C语言程序设计教案 奇数阶魔方阵 一、提出问题 所谓“奇数阶魔方阵”是指n为不小于3的奇数的魔方阵。这类魔方阵的形式多样,这里我们仅讨论其中的一种形式的正规魔方阵。例如:3阶、5阶和7阶的魔方阵如图3 – 4 所示。 3039*********416357,46132022,***2192***211***2414322314049图3 – 4 3阶5阶和7阶魔方阵 ***5 44431211202容易知道,这三个魔方阵的魔方常数分别是15、65和175。 现在要求给出:能让计算机自动输出类似图3 – 4 所示的n阶奇数魔方阵的算法,其中n为任意给定的一个不小于3的奇数。 二、简单分析 决定“奇数阶魔方阵”的关键是要按要求决定其方阵中的各个数字。观察图3 – 4中的三个奇数阶魔方阵,不难发现: 1.由于是正规魔方,故所填入的n 2个不同整数依次为1、2、3、…、n 2 ; 2.各行、列和对角线上的数字虽各不相同,但其和却是相同的。这表明,其魔方常数可由公式n(n 2 + 1)/ 2得到。 3.数字在阵列中的次序,并没有遵从阵列单元的行、列下标的顺序,但数字“1”却始终出现在阵列第一行的正中间位置,而数字“n 2”也始终出现在阵列第n行的正中间位置,这说明阵列中的数字排列应该是有一定规律的。 通过对两个奇数阶魔方阵的简单分析,下面几个基本问题必须得到解决: ◆ 奇数阶魔方阵中的数字有些什么规律? ◆ 数字“1”的位置应如何确定? C语言程序设计教案 三、设计准备 1.奇数阶魔方阵中的数字规律 通过对奇数阶魔方阵的分析,其中的数字排列有如下的规律:(1)自然数1出现在第一行的正中间; (2)若填入的数字在第一行(不在第n列),则下一个数字在第n行(最后一行)且列数加1(列数右移一列); (3)若填入的数字在该行的最右侧,则下一个数字就填在上一行的最左侧;(4)一般地,下一个数字在前一个数字的右上方(行数少1,列数加1); (5)若应填的地方已经有数字或在方阵之外,则下一个数字就填在前一个数字的下方。(一般地,n的倍数的下一个数字是在该数的下方。) 816按照上述的规律,我们来完成3阶的魔方阵:357 4921第一步:将“1”填入1行2列的位置,即(按规律(1)); 1第二步:将“2”填入3(最后)行3(= 2 + 1)列的位置,即 (按规律 2(2)); 1第三步:将“3”填入2行1列的位置,即3(按规律(3)); 21第四步:将“4”填入3行1列的位置(“3”的下面);即3(按规律(5)) 422 C语言程序设计教案 1第五步:将“5”填入2行2列的位置;即35216(按规律(4)); 4第六步:将“6”填入1行3列的位置,即352(按规律(4)); 416第七步:将“7”填入2行3列的位置(“6”的下面),即357(按规律(5)); 42816第八步:将“8”填入1行1列的位置,即357(按规律(3)); 42816第九步:将“9”填入3行2列的位置,即357(按规律(2))。492至此,一个3阶魔方阵构造完成了。2.数字“1”的位置确定方法 由于数字“1”要填写在魔方阵第一行的正中间,因此我们只需要确定第一行的正中间单元的列下标即可。 考虑到对于一个奇数阶魔方阵来说,它的每一行都有奇数个位置,所以“正中间的位置”就必然存在。容易知道,一个n(为奇数)阶魔方阵第一行的正中间单元的列下标为整数(n + 1)/ 2。于是数字“1”应填写在魔方阵列的第1行第(n + 1)/ 2列处。 C语言程序设计教案 四、实施步骤 1.算法编制的工作顺序: 有了上述的设计准备,我们所要的算法可按如下的工作顺序编制: 第一步:输入魔方阵的阶数n(为奇数),并以此定义一个二维数组; 第二步:确定所谓“正中间位置”的列下标值,以及应填入的最大数字; 第三步:进行完成魔方阵的填写工作; 第四步:输出已完成的奇数阶魔方阵。2.变量设置: N :表示魔方阵的阶数(为奇数); A :表示魔方阵的二维数组; I :数组A的行序号; J :数组A的列序号; R :填入的数字; S :对角线上各数字之和。 3.参考框图:如图3 – 5 所示。4.框图说明:整个框图应分为三个功能部分: 第一个部分的功能是完成奇数N的输入,并定义二维数组,完成有关元素的数值计算,同时能实现当N不是奇数时自动结束。图3 – 5 处理“奇数阶魔方阵”问题的框图 第二个部分的功能是完成魔方阵的填写工作。 填写并不是按数组A的下标顺序进行,而是通过对有关规律的判断确定下标I和J的不同值来进行。其中涉及到了判断“R是N的整数倍?”,这可以通过判断是否有等式R – INT(R / N) N = 0 成立来实现。 第三个部分的功能是完成输出魔方阵和计算相应魔方常数的工作。 计算相应魔方常数的工作是通过对魔方阵的对角线中各元素数值来实现,即在准备输出打印元素A(I , I)时,通过累加方式S = S + A(I , I)来实现。 C语言程序设计教案 5.参考算法 第01步:输入非负整数N,并定义数组 A(N , N); 第02步:若 N – INT(N / 2) 2 = 0,则结束。第03步:让J (N + 1)/ 2 , C N N , 且I 1; 第04步:让 R 1; 第05步:若R > C , 则执行第16步; 第06步:让 A(I , J) R; 第07步:若R – INT(R / N) N = 0 , 则执行第13步; 第08步:让I I – 1 ; 第09步:若I + 1 = 1,则让I N; 第10步:让J J + 1; 第11步:若J – 1 N,则执行第15步; 第12步:让J 1 , 并执行第15步; 第13步:让I I + 1。若I – 1 N,执行第15步; 第14步:让I 1 ; 第15步:让R R + 1,执行第05步; 第16步:让 S 0 , I 1 ; 第17步:若I > N , 则执行第24步 ; 第18步:让 S S + A(I , I); 第19步:让J 1; 第20步:若J > N , 则执行第13步; 第21步:在位置 4 J 处输出 A(I , J); 第22步:让J J + 1,并执行第20步; 第23步:换行,让I = I + 1 , 并执行第17步; 第24步:输出 S,结束。 参考算法的编制与框图稍有不同,但功能是一样的。其中: 第01步至第03步为第一部分,完成奇数的输入,以及有关的准备工作。当输入的N不是奇数时,会自动结束。第04步至第15步完成魔方阵的填写工作。第16步至第24步完成输出魔方阵和计算相应魔方常数的工作。 C语言程序设计教案 五、评估反思 应当说,奇数阶魔方阵的形式是多种多样的,这里我们仅仅只对其中的一种形式加以讨论。这里所编制的参考算法从理论上看可以实现对指定形式的任何大小“奇数阶魔方阵”的输出,但在实际输出时应考虑输出设备的相关条件。 在参考算法中,第04步至第15步这部分是整个算法的核心部分,其功能是完成整个魔方的数字填入工作,因此其编制的思想、用到的一些处理方阵元素的技巧和经验,应引起我们的注意。 1.充分利用规律间共同特性。 在这部分里我们通过若干次对下标值的判断,巧妙地将奇数阶魔方阵应当遵循的规律(2)、(3)和(4)结合起来,使魔方阵的填写工作能得以顺利进行。这是因为奇数阶魔方阵要求的五个规律中,规律(2)、(3)和(4)与单元的下标有直接的关系。 2.选择首次判断对象的要求。 在这部分里我们首先进行的是对填入数字R是否是阶数N的整数倍的判断,这实际上是将奇数阶魔方阵的规律(5)作为主要的判断标准。那么为什么不用另外的四个规律来作为主要的判断标准呢?这主要是考虑到对于要填入的数字,在奇数阶魔方阵的五个规律中,只有规律(5)将该数字直接与阶数联系起来,而另外四个规律则没有(仅仅与填入单元的下标值有直接的联系)。这告诉我们,算法的编制应注意那些具有单一性特点的事实、特性或规律等等。 3.有关魔方常数的得到。 要得到魔方常数,最直接的方法是通过公式S = n(n 2 + 1)/ 2来计算,但这样做不能显示整个魔方阵的构造是否正确。在参考算法中,我们是通过累加魔方阵对角线中各元素数值来实现的,这样做的好处有,其一是体现了数字累加方式在算法编制中的作用,其二是显示了所构造的魔方阵是否正确。当然,我们也可以通过累加魔方阵某行或某列中各元素数值来实现,只不过设计的步骤要稍多一些,因为需要从n行(列)中确定某行(列)的步骤。 4.关于魔方阵的验证。 本参考算法中没有设计利用魔方常数来判断所完成的方阵是否是魔方阵的步骤,但设计这一功能并不困难。比较方便的做法可以为:在第一部分加入用公式计算魔方常数的步骤,将第三部分分成输出方阵和验证方阵两部分。在验证部分里,设计分别计算各行、各列及对角线中各数字和的步骤,以及将这些数字和与前面计算出的魔方常数进行比较的步骤。若对此有兴趣,不妨自己动手试试。 C语言程序设计教案 六、要点回顾 1.数学思想:构成奇数阶魔方阵应当遵循的五个规律; 2.常用公式:判断“R是N的整数倍”的等式R – INT(R / N) N = 0 ; 3.算法技巧:利用累计方式计算魔方常数和完成魔方阵输出的方法。4.实用方法:判断整数R是否是整数N的整数倍的方法。 方阵解说词 英姿飒爽 神采飞扬,昂首阔步,意气风发!迎面走来的是能源学院方队,挺拔的身姿迎着金秋的微风,明净的脸上洋溢着青春的自信! 听,嘹亮的声音,昭示出他们的蓬勃朝气;看,炯炯的目光,展示着他们的自信刚强。他们用青春的激情放飞明天的梦想;他们用拼搏的精神谱写今朝的辉煌!炎炎烈日下,他们勤学苦练;绵绵阴雨中,他们稳扎稳打。待到风云齐聚会,便上青天摘玉盘。今天,他们在汗水中磨练意志。明天,他们将为母校增光添彩! 四(2)班解说词 : 披着晨光,带着朝露,踏着青春的步伐,伴着激扬的旋律,四<2>班向我们走来。他们个个精神饱满,英姿飒爽。整齐的步伐踏着他们的坚定,灿烂的微笑写着他们的热情,嘹亮的口号体现着他们的实力。他们团结友爱,勤奋好学。让我们一起衷心的祝愿,祝愿4<2>班取得优异的比赛成绩! 1.水碧云天,秋风劲朗。旌旗蔽空,战鼓擂响。且看人文学院方阵的战士们英姿飒爽!十四天早出晚归,他们在血汗里种下坚韧;十四天风雨同舟,他们在磨砺中收获成长!晨钟暮鼓,是他们铁一般的秩序;披星戴月,是他们钢一般的坚强!用伤疤雕刻勋章,用汗水铸造辉煌。博学笃行传薪火,厚德重法弦歌昂。九州英才聚华电,共谱人文新华章!看我人文学子今朝挥剑破云,扬眉四方,旗开得胜,独擅胜场! 2.回响在操场上空的震天口号,荡漾着热血青年力争上游的壮志豪情,现在走来的是人文学院的队列方阵。训练场上,他们挥汗如雨,以苦为乐。烈日下挥拳踢腿,风雨中身姿挺拔,操场上留下了他们坚定的足迹,操场上回荡着他们响亮的口号。同学们,面对眼前鲜艳的五星红旗,请鼓起你进取的勇气,面对主席台上领导欣赏的目光,请亮出你军人的风采,把胸中激荡的豪情放飞蓝天,用脚下有力的足音叩响大地! 3.现在迎面而来的是人文学院的方阵,看,那矫健的步伐正象征着他们永不言弃的精神,那响亮的口号代表着他们奋发向上的动力,那严整的军姿更彰显这他们永争第一的决心。整齐有力的步伐是他们前进的鼓点,坚定昂扬的精神是他们奋斗的源泉。他们将秉承“艰苦奋斗,自强不息”的精神,勇敢向前,追求卓越,编织美丽的梦想,渲染七彩的人生。 4.向着朝阳,迈着健步,迎面走来的是英姿飒爽的人文学子。他们并肩踏着青春的旋律,和着欢乐的乐曲,迈着矫健自信的步伐,整齐划一,气宇轩昂。那一阵阵掷地有声的步伐,那一声声铿锵有力的口号,无不洋溢着人文学子勃勃的生机。他们风华正茂,雄姿英发,他们乐观自信、奋发向上。听,嘹亮的声音,昭示出他们的蓬勃朝气,看,炯炯的目光,展示着他们的自信刚强。今天的成果来自昨天的汗水,向前吧,美好的明天从现在铸造!第二篇:奇数阶魔方阵算法分析
第三篇:方阵解说词
第四篇:方阵解说词
第五篇:方阵解说词