![d6cc512b46c1187cf29e946d002193ce.png](https://i-blog.csdnimg.cn/blog_migrate/e04de44fc763fda97da30dc462675f23.jpeg)
在对数组排序时,我们常把数组分成已排序区域和待排序区域,并使用左右边界来划分待排序区域的范围;对分查找时我们也引入了左右边界的概念。可见左右边界在数组中是一个非常重要的概念,它在分段处理数组时可以帮助我们清晰地描述某个区间的数组元素,从而正确理解相关处理过程。
2019年4月信息技术选考真题卷第17题
一 题目17.【加试题】给定m个区间和1个数组(有n个元素),现要求根据各区间限定的取值范围,将数组依次分隔成m+1个段。具体分割方法如下:
第1段是从数组首个元素开始、元素值都属于第1区间的最长连续元素段。如果首个元素不属于第1区间,则第1段元素个数为0;
第1段分割后的剩余元素,用同样的方法来依次分割第2段、第3段、…、第m段;
第m段分割后的剩余元素分割到第m+1段(剩余段)。
若第p(1≤p≤m-1)段末尾连续元素的值也同时属于第p+1区间,则这块连续元素称为第p段“重叠块”,该段其余部分称为第p段“非重叠块”。由于不存在第m+1区间,这里特别规定:第m段的全部元素都分割到m段“非重叠块”,第m段“重叠块”的元素个数为0,一个数组分段示例如下图。图中数组第1个元素10不属于第1区间[0,5],因此第1段的元素个数为0。10和20属于第2区间,而33不属于第2区间,因此第2段只包含10和20两个元素。第3段末尾连续3个元素的值也同时属于第4区间,因此,第3段“非重叠块”包含33,58,46,第3段“重叠块”包含55,62,69。
(1)给定2个区间依次为[10,50]、[30,80],数组各元素为“12,44,34,45,66,50,45,70”,则第1段“重叠块”中的元素个数为 个。
(2)小李根据上述描述,设计了一个统计各段“非重叠块”、“重叠块”和剩余段中元素个数的算法。算法的VB程序如下,请在划线处填入合适的代码。
Const n = 18, m = 6
Dim a(1 To n) As Integer
Dim b(1 To 2 * m) As Integer
'b(1)、b(2)为第1区间的下限和上限, b(3)、b(4)为第2区间的下限和上限,…
Dim c(1 To 2 * m + 1) As Integer
'数组c用于保存统计结果:
'c(1)、c(2)分别存储第1段“非重叠块”和“重叠块”的元素个数,
'c(3)、c(4)分别存储第2段“非重叠块”和“重叠块”的元素个数,…
'c(2m-1)存储第m段"非重叠块"元素个数,c(2m)存储第m段"重叠块"元素个数(值为0)
'c(2m+1)存储剩余段元素个数
Private Sub Command1_Click()
Dim i As Integer, p As Integer, L As Integer, LL As Integer
'读取n个数据并保存在数组a中,代码略
'读取m个区间的下限和上限并保存在数组b中,代码略
For i = 1 To 2 * m + 1
c(i) = 0
Next i
i = 1: p = 1
L = 0: LL = 0
Do While ①
If IsIn(i, p) Then
If IsIn(i, p + 1) Then
LL = LL + 1
Else
②
LL = 0
End If
i = i + 1
Else
c(2 * p - 1) = L
c(2 * p) = LL
L = 0: LL = 0
p = p + 1
End If
Loop
If i <= n Then
c(2 * p - 1) = n - i + 1
Else
c(2 * p - 1) = L
c(2 * p) = LL
End If
'输出统计结果,代码略
End Sub
'函数IsIn用来判断a(i)值是否属于第p区间
Function IsIn(i As Integer, p As Integer) As Boolean
If p > m Then
IsIn = False
Else
If ③ Then IsIn = True Else IsIn = False
End If
End Function
二 考查知识点 数组分段处理、子序列左右边界的概念、自定义函数功能分析。要求学生熟练掌握数组的基本操作,能根据题意分析各个变量的含义,能用左右边界的概念来划分子序列的范围,并熟悉自定义函数的语法。 三解析 此题背景信息繁复,数据结构复杂,涉及变量较多,很考验学生的阅读理解能力。但算法说明清晰,示例数据也很恰当,如果有足够时间,应该不难理解题意,尤其是第 3空,根据题目说明和注释信息,不难填出此空。 我们先采用在代码中添加注释的方法解析算法如下:题目中的代码分别用变量L和LL来表示第p段元素中“非重叠块”和“重叠块”的元素个数,只使用一重循环,通过遍历数组a,判断a(i)是否属于第p段元素,利用一个嵌套If语句,分别计算出L和LL的值。其中LL递增和清零的表达式容易理解,但L的计算式有一定难度,容易错填为L = L + 1,若是这样,则L的含义变成了统计第p段中属于区间p但不属于区间p+1的元素数量。
因为“重叠块”的特征是第p段末尾的连续元素,故一旦出现不属于区间p+1的元素,则LL必须归零,同时把前面累积的LL值累加到L上,即L = L + LL + 1。
我们可以从另一个角度来理解题意:因为第p段元素的总数量是“非重叠块”和“重叠块”的元素个数之和,如果我们能够把第p段元素的长度(即元素总量)求出来,再减去LL,就得到了“非重叠块”的元素个数。
此外,我们还可以把处理第p段元素的过程放在一个内层do循环中,这样便于理解LL的计算过程,而且代码更简洁。
为了充分利用题目的原有代码,我们只修改了核心代码,且未定义新的变量,但是变量L不再表示“非重叠块”的长度,而是指向第p段元素的左边界,然后使用变量i来遍历数组a,使得在内层do循环结束后(i-1)刚好指向第p段元素的右边界,这样第p段元素的长度恰好为i-L,若用LL表示“重叠块”的长度,则“非重叠块”的长度为i-L-LL。
相关代码如下:
(1) 3
(2) ① i<=n And p<=m 或其他等价表达式
② L=L+LL+1或其他等价语句
③ a(i)>=b(2*p-1) And a(i)<=b(2*p) 或其他等价表达式五拓展思考本题给出的“重叠块”概念很有趣,在很多地方都有应用,“字符串消消乐”游戏就是一例。
“字符串消消乐”游戏说明:从Text1框输入一个字符串,程序会把相邻的相同字符消除,所有相邻的相同字符被消除后剩余字符会重新拼接成新的字符串,再按照相同的规则消除字符,直到所有相邻的字符都不相同或变成空串为止,输出最后获得的字符串。
例如,输入字符串"aabcdddcd",点击“运行”按钮后输出字符串"bd";输入字符串"aabdcdddcdb",点击“运行”按钮后输出空字符串;输入字符串"aabccbbbca",点击“运行”按钮后输出字符串"bca"。
算法的VB程序如下,请在划线处填入合适的代码。
参考代码1:
Private Sub Command1_Click()
Dim s1 As String, s2 As String
Dim i As Integer, j As Integer
s1 = Text1.Text
Do While Len(s1) > 1
s2 = ""
i = ①
Do While i <= Len(s1) '消除相邻的相同字符
For j = i + 1 To Len(s1)
If Mid(s1, i, 1) <> Mid(s1, j, 1) Then ②
Next j
If j = i + 1 Then s2 = ③
i = ④
Loop
If s2 = s1 Then ⑤ '没有发生消除操作,跳出循环
s1 = s2 '重复消除过程,直到无法消除为止
Loop
Label2.Caption = s1
End Sub
参考代码2:
Private Sub Command2_Click()
Dim s1 As String, s2 As String, ch As String
Dim i As Integer, flag As Boolean
s1 = Text1.Text
flag = True
Do While flag And Len(s1) > 1
flag = ⑥ '默认没有消除字符
'单独处理第一个字符
If Mid(s1, 1, 1) = Mid(s1, 2, 1) Then s2 = "" Else s2 = Mid(s1, 1, 1)
For i = 2 To Len(s1) '最后一个字符无需单独处理,想想为什么?
ch = Mid(s1, i, 1)
If ⑦ Then
flag = True '发生了消除操作
Else
s2 = ⑧
End If
Next i
s1 = s2 '重复消除过程,直到无法消除为止
Loop
Label2.Caption = s1
End Sub
六拓展思考答案① 1 ② Exit For
③ s2 + Mid(s1, i, 1)
④ j ⑤ Exit Do
⑥ False
⑦ ch = Mid(s1, i - 1, 1) Or ch = Mid(s1, i + 1, 1)
⑧ s2 + ch
写在后面为了保证解析的原创性和思维的独特性,我都是独立解题后,先不看答案(除非题目不会做),直接把解析写好,再去看答案。
当然,如果发现参考答案有更好的思路,我还是很乐于学习和借鉴的。同时,由于本人水平有限,解析中难免出现疏漏甚至错误之处,敬请谅解。
无论是赞同还是反对我的看法,都请你给我留言。如果你有新的想法,千万不要憋在心里,请发出来大家一起讨论。让我们相互学习,共同进步!
需要本文word版的,可以加入“选考VB算法解析”知识星球参与讨论和下载文件,“选考VB算法解析”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。
我们专注选考VB算法,感兴趣就一起来!
相关优秀文章:
阅读代码和写更好的代码
最有效的学习方式
选考VB算法解析之2018年11月高考真题卷第16题
选考VB算法解析之2018年11月高考真题卷第17题
选考VB算法解析之2019年4月高考真题卷第16题