左上-右下对称分布轮流填充正方形数字阵列
“N阶左上-右下对称分布轮流填充正方形数字阵列”其特征是:让从1~N×N整数从左上到右下连续对称分布轮流填充形成的正方形数字阵列。例如8阶8×8左上-右下对称分布轮流填充正方形数字阵列输出的结果是这样子的:
任意输入一个N数字就能自动输出N×N正方形的数字阵列,还要求1-2-3-4-5……先占据正方形的对角线位置,其他连续而来的数字还必须轮流在对角线两侧依次按座入号排列下来。这看似相当困难的事的背后其实完完全全是建立在数学思维的基础之上的。而且还要再理解一个新的编程“工具”——“数组”。像前些次讲的三角形数字阵列那样直接填写输出是做不到的。因为要输出的是按照特殊规律排列的正方形的数字阵列,一行相邻的两个数字之间基本上不存在数字连续的关系,所以需要建立“二维数组”,其中一“维”管数字在哪一“行”,另一维数组管数字在这一行的哪一“列”。“数组”其实是数据的存储空间。我们先按规律往数组里面赋值填写数字,所有数字都按部就班填写好了,然后就整体输出“数组”里面的数值,这就看到了我们预先需要的“数字阵列”。关于“数组”的更具体详细的概念请阅读林老师编著的《新编PCLogo教程-习题集》、《MSWLogo讲义Plus》(完全兼容FMSLogo)。
能够输出任意N的“N阶左上-右下对称分布轮流填充正方形数字阵列”的源程序如下。
(1)由于填写数字的规律比较复杂,只能预先建立二维数组,待对数组空间填充完毕后再输出显示结果。
(2)最先填写从左上方到右下方对角线上的空格。这是比较容易的事。
(3)方阵的右上方和左下方互为“镜像”,在编程语句上体现为:
make "h
1 make "v
:i
make "h
:i make "v 1
(4)在填充过程中始终进行make "k
:k+1操作,所以能够形成1~:n*:n的连续数字序列。
(5)全部填充完毕后,用tp过程输出结果,并适当填补相邻数字之间的空格使得数据对齐。
to fzheng
:n ;填写:n阶斜方阵主程序
make "a mdarray se :n
:n
;建立储存数字的数组空间
for [i 1 :n][for [j 1 :n][mdsetitem se
:i :j :a 0]]
;先对全部空间清零
for [i 1 :n][mdsetitem se :i :i :a
:i] ;对中心斜行填入1-:n数值
make "k :n+1
;继斜行之后连续进行自动增长1的操作以形成1-:n*:n数字
for [i 2 :n][tk]
;对上下两个三角形区域2-:n斜行进行填空
for [i 1 :n][for [j 1
:n][tp]pr[]pr[]] ;输出方阵
end
to
tk ;方阵上下三角形区域填空子程序
;=========对右上方进行填空========
make "h
1 ;横列计数
make "v
:i ;纵行计数
for [j 1
(:n-:i+1)][
mdsetitem se :h :v :a :k
;将数字:k填入空格
make "k :k+1
;下一个:k增长1
make "h :h+1
;
:h:v增长形成移位到下一个空格
make "v :v+1
]
;=========对左下方进行填空========
make "h
:i ;横列计数
make "v
1
;纵行计数
for [j 1
(:n-:i+1)][
mdsetitem se :h :v :a :k
;将数字:k填入空格
make "k :k+1
;下一个:k增长1
make "h :h+1
;
:h:v增长形成移位到下一个空格
make "v :v+1
]
end
to
tp ;输出方阵兼数据间隔格式距离处理
make "sz mditem se :i :j
:a ;读出当前格数据
type :sz
;显示输出当前格数据
if :sz<100 [type char
32] ;在1、2位数后面补充空格
if :sz<10 [type
char 32]
type char 32
;形成两个数字间的间隔
end
运行程序的结果表明,这个程序的功能是十分令人满意的。对于任意对应的数值N,都能输出完美的正方形数字方阵。
加载中,请稍候......