说在前面
字符串加密和二维矩阵都曾多次在选考真题卷中出现,是必须掌握的经典算法。
浙江省十校联盟2020年10月高三联考卷第15题考查了自定义函数、字符串加密、进制转换和二维矩阵等知识点,综合性强,难度大。
其中使用一维数组存储二维矩阵是经典问题,相关操作变例也很多,笔者尝试进行解析,并在拓展思考中对该问题做了进一步探讨,对于高三学生复习迎考有一定帮助。
浙江省十校联盟2020年10月高三联考卷第15题
一题目
二考查知识点
字符串加密、进制转换、自定义函数和二维矩阵,要求学生熟悉字符串基本操作,理解十进制转二进制的基本原理,知道如何调用自定义函数,并熟练掌握使用一维数组表示二维矩阵的方法。
三解析
本题模拟字符串加密过程,算法较为复杂,重点考查使用一维数组表示二维矩阵的方法。
第①空相对简单,只要读懂算法第一步“把每个字符对应成一个数值”的含义,应该能做出来。
第②空难度较大,其所在代码块的功能是将数组a的元素按列序存储到蛇形矩阵中。一般使用二维数组来存储二维矩阵,但由于选考VB中未涉及二维数组语法知识,所以要用一维数组来存储二维矩阵,其方法为:对于总列数为C的矩阵,第i行第j列的元素可以表示为b((i-1)*C+j)。
注意到每处理完矩阵的一个列以后,列编号j增1,同时通过修改变量d来改变前进方向,故第②空答案可以为k Mod R = 0。
第③空所在代码块的功能是将二进制数字串转换成十六进制数,主要考查自定义函数,根据算法原理和Bin2Hex函数的参数设置,不难写出答案。
出错代码所在处的功能是把存储在数组b中的矩阵按行序进行拼接,用变量s存储每一行的数字串,再顺序拼接到变量t中,并在t的尾端补”0”(如果需要的话),确保其总长度为4的倍数。在计算补”0”的数量时,题目代码采用了两次取模的技巧,非常巧妙,但理解起来有一定难度,也可以采取如下写法:
Do While Len(t) Mod 4 <> 0
t = t + "0"
Loop
接下来为代码添加注释分析如下:
四 答案
(1) B (1 分)
(2)① x = Asc(ch) – 64 (1分)
② k Mod R = 0 (2 分)
③ ans + Bin2Hex(Mid(t, i, 4)) (2分)
(3)s = s + CStr(b((i - 1) * C + j)) (1分)
五 拓展思考
题目重点考查使用一维数组表示二维矩阵的方法,为了帮助大家进一步理解该知识点,我设置了几个问题,请大家认真思考,并将缺失的代码补充完整。
(1)已知行号和列号求元素下标。如图1所示,有一个大小为3*4(3行4列)的二维矩阵,将其按行序存储到一维数组a(1 to 12)中。观察表格可知,a(1)=51,a(2)=52,…a(12)=62。请问矩阵中第2行第3列的元素,在数组a中的下标和值分别是多少?推广到一般情形,对于最大列数为C的二维矩阵,其第i行第j列的元素在数组a中的下标是多少?
(2)已知元素下标求行号和列号。如图1所示,有一个大小为3*4(3行4列)的二维矩阵,将其按行序存储到一维数组a(1 to 12)中。观察表格可知,a(5)在矩阵中的行号i=2,列号j=1。请问a(10)在矩阵中的行号和列号分别是多少?推广到一般情形,对于最大列数为C的二维矩阵,数组元素a(p) 在矩阵中的行号和列号分别是多少?
(3)转置矩阵。如图2所示,原矩阵大小为4行5列,将其行列转置得到新矩阵,则新矩阵大小为5行4列,且原矩阵中第i行第j列的元素刚好等于新矩阵中第j行第i列的元素。
(4)翻转矩阵。如图3所示,将原矩阵以竖直中心轴水平翻转得到新矩阵。
下面的程序实现了转置矩阵和翻转矩阵功能,请认真阅读代码,并将缺失的代码补充完整:
Const n = 100
Dim a(1 To n) As Integer, b(1 To n) As Integer
Dim R As Integer, C As Integer
Dim s As String
Private Sub Form_Load()
Dim i As Integer, j As Integer
R = 4: C = 5 '矩阵大小为4行5列
For i = 1 To R * C
a(i) = i + 10
Next i
For i = 1 To R
s = ""
For j = 1 To C
s = s + Str(① )
Next j
List1.AddItem s
Next i
End Sub
Private Sub Command1_Click()
Dim i As Integer, j As Integer
For i = 1 To R '求转置矩阵b
For j = 1 To C
b(② ) = a((i - 1) * C + j)
Next j
Next i
List2.Clear
For i = 1 To C '输出矩阵b
s = ""
For j = 1 To R
s = s + Str(③ )
Next j
List2.AddItem s
Next i
End Sub
Private Sub Command2_Click()
Dim i As Integer, j As Integer, t As Integer
For i = 1 To R '将矩阵a以竖直中心轴水平翻转
For j = 1 To C \ 2
t = a((i - 1) * C + j)
a((i - 1) * C + j) = a(④ )
a(i * C - j + 1) = t
Next j
Next i
List2.Clear
For i = 1 To R '输出矩阵a
s = ""
For j = 1 To C
s = s + Str(a((i - 1) * C + j))
Next j
List2.AddItem s
Next i
End Sub六 拓展思考答案
(1)矩阵中第2行第3列的元素,在数组a中的下标和值分别是7和57,即a(7)=57;
推广到一般情形,对于最大列数为C的二维矩阵,其第i行第j列的元素在数组a中的下标p=(i-1)*C+j。
(2)a(10)在矩阵中的行号和列号分别是3和2,即10=(3-1)*4+2;
推广到一般情形,对于最大列数为C的二维矩阵,数组元素a(p)在矩阵中的行号i=(p-1)\ C + 1,列号j=(p-1) Mod C + 1
(3)① a((i - 1) * C + j)
② (j - 1) * R + i
③ b((i - 1) * R + j)
④ i * C - j + 1