![cac23673792a17d66b2864005d58b0cf.png](https://i-blog.csdnimg.cn/blog_migrate/05d46ff34b14dc6230977b0ee2480714.jpeg)
矩阵转换是线性代数中常见的操作,使用二维数组实现矩阵转换的算法是很简明的,但由于高考VB中不涉及二维数组,只能用一维数组来模拟实现,因此加大了算法难度,同时也训练了学生的思维。
2017年11月高考技术真题卷第17题
一 题目17.【加试题】由数组a生成数组b的方法描述如下:
1)将数组a中的n个元素依次分割出若干个数据块,每个数据块有m×m个元素,m最大值为8,最小值为2。分割时,按尽可能大的数据块进行分割;
2)对每个分割出的数据块用“方阵转换法”进行转换,每次转换后得到的数据块依次存储在数据b中;
3)数组a分割后的剩余元素(个数小于4),直接依序存储到数组b中。
例如n=140时,可依次分割出3个数据块,元素的个数分别为64(8×8)、64(8×8)、9(3×3),剩余元素为3个。
“方阵转换法”过程如下:将数据块中m×m个元素按行序排列成一个数字方阵,从该数字方阵中按列序得到转换后元素的次序。以3×3数据块为例,转换过程如下图所示:
小明依据上述描述设计了如下VB程序。请回答下列问题:
(1)当n=120时,分割出的第3个数据块元素个数为 。
(2)请在划线处填入合适的代码。
Const n = 120
Dim a(1 To n) As Integer
Dim b(1 To n) As Integer
Private Sub Command1_Click()
Dim m As Integer, i As Integer
Dim Start As Integer '当前未分割数据的第1个元素下标
Dim Left As Integer '当前未分割数据的个数
Dim pa As Integer '数组a的下标
Dim pb As Integer '数组b的下标
'读取n个转换前的数据,依次存储到a(1)、a(2)、……a(n)中,代码略
m = 8
Start = 1
Left = n
Do While Left > 3
If Left < m * m Then
m = ①
Else
pa = Start
pb = Start
For i = 1 To m * m
b(pb) = a(pa)
pb = pb + 1
If i Mod m = 0 Then
②
Else
pa = pa + m
End If
Next i
③
Start = Start + m * m
End If
Loop
For i = Start To n
b(i) = a(i)
Next i
'依次输出转换后数据b(1)、b(2)、……b(n)中,代码略
End Sub
二 考查知识点数字方阵,二重循环,要求学生能根据示例数据和数字方阵转换图片,结合代码分析算法逻辑,从而填出缺失的代码。
三解析本题题干没有给出详细的转换算法,需要自己结合示例数据和数字方阵图像分析算法思路。我们结合代码给出分析注释如下:
第1空,m表示当前数字方阵的大小,题目采用枚举法,逐个减小m的值来寻找m的最大可能值,找到满足条件的最大m值后,再进行转换工作。
Start存储数字方阵左上角元素的下标,Left存储剩余元素的个数,因为每转换好一个数字方阵后,就要更新Left和Start的值,根据语句Start = Start + m * m,由此可以得出第3空应该填Left = Left - m * m。
第2空比较难,需要对照两个数字方阵各元素的位置,找到pa的变化规律。观察数字方阵可知,当pa指向第m行,即i Mod m = 0时, 其后续元素的位置位于下一列的顶端,即pa = Start + i \ m 或 pa=pa-(m-1)*m+1;否则pa指向其下方的元素,即pa = pa + m。由此可以填出第2空。
四 答案(1)4
(2)①m=m-1或 m=int(sqr(left))
②pa=start+i\m 或pa=start+i/m 或pa=pa-(m-1)*m+1 或 pa=start+(pa-start+1) mod m
③left=left-m*m
五拓展思考本题在处理某个数字方阵的转换工作时,是把方阵看做一个整体,一次性遍历整个方阵,逐个处理的(对应语句为For i = 1 To m * m),这样需要判断第i个元素的位置,根据pa当前所指元素所在的行数来更新pa的值,使用分支结构,提高了思维的难度。
事实上可以使用更直接的思路,就是逐列转换各个元素,按照从左到右,从上到下的顺序依次处理,代码更简明。
此外,在计算当前方阵的规模时,也可以不用枚举的方法来确定m的值,而是直接写出解析式:m = Int(Sqr(Left)),当然,若计算出m > 8则设置m = 8。
请根据上述分析,写出相关代码。
六拓展思考答案算法1:逐列转换各个元素。
Start = 1
Left = n
Do While Left > 3
m = Int(Sqr(Left))
If m > 8 Then m = 8 'm最大为8
pa = Start
pb = Start
For i = 1 To m '第i列
For j = 1 To m '第j行
b(pb) = a(pa)
pb = pb + 1
pa = pa + m '下一行
Next j
pa = Start + i '下一列
Next i
Left = Left - m * m
Start = Start + m * m
Loop
For i = Start To n
b(i) = a(i)
Next i
算法2:模拟二维数组实现矩阵转换的算法,即b(j, i) = a(i, j),可以得到更简明的代码。
Start = 0 '注意start初值为0
Left = n
Do While Left > 3
m = Int(Sqr(Left))
If m > 8 Then m = 8 'm最大为8
For i = 1 To m '第i行
For j = 1 To m '第j列
pa = Start + (i - 1) * m + j
pb = Start + (j - 1) * m + i
b(pb) = a(pa)
Next j
Next i
Left = Left - m * m
Start = Start + m * m
Loop
For i = Start To n
b(i) = a(i)
Next i
写在后面为了保证解析的原创性和思维的独特性,我都是独立解题后,先不看答案(除非题目不会做),直接把解析写好,再去看答案。
当然,如果发现参考答案有更好的思路,我还是很乐于学习和借鉴的。同时,由于本人水平有限,解析中难免出现疏漏甚至错误之处,敬请谅解。
无论是赞同还是反对我的看法,都请你给我留言。如果你有新的想法,千万不要憋在心里,请发出来大家一起讨论。让我们相互学习,共同进步!
需要本文word版的,可以加入“选考VB算法解析”知识星球参与讨论和下载文件,“选考VB算法解析”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。
我们专注选考VB算法,感兴趣就一起来!
相关优秀文章:
阅读代码和写更好的代码
最有效的学习方式
选考VB算法解析之2017年4月高考真题卷第12题
选考VB算法解析之2017年4月高考真题卷第16题
选考VB算法解析之2017年4月高考真题卷第17题