![1b9a505127011ff1bdc5ca8790c8c82f.png](https://i-blog.csdnimg.cn/blog_migrate/78949493100eee66b466973991aff45c.jpeg)
高考真题既是考试大纲的集中体现,也是高考复习的风向标,研究高考VB算法题的出题方式,算法类型和题目难度,有助于教师专题复习时合理选择练习用题,科学制定教学计划。
自从2017年4月高考真题卷第17题考查了桶排序算法思想后,接下来几年的联考卷和模拟卷就多次出现了与之相关的题目,桶排序算法也一跃成为继冒泡排序和选择排序之后的又一个必学必会之经典排序算法。
2017年4月高考真题卷第17 题一 题目17.【加试题】小王编写了一个依据成绩计算名次的VB程序,成绩为0到100之间的整数。算法的基本思想:先统计每个分数的个数,然后按照分数从高到低依次计算每个有效分数(该分数的个数不为0)对应的名次,分数相同时名次并列。最高分为第1名,该分数的名次与个数之和为下一个有效分数的名次,以此类推。程序用数组A存放每个分数对应的个数,数组B存放每个分数对应的名次。例如,下表中最高分100有2个,并列第1名,则分数96的名次为分数100的名次加上分数100的个数,即第3名。
分数 | 100 | 99 | 98 | 97 | 96 | 95 | 94 | … | 0 |
个数(A数组) | 2 | 0 | 0 | 0 | 1 | 0 | 3 | … | 0 |
名次(B数组) | 1 | 3 | 4 | … |
程序运行时,学生数据显示在列表框List1中,单击“计算”按钮Command1,计算结果显示在列表框List2中,程序运行界面如图所示。
实现上述功能的VB程序如下,请回答下列问题:
(1)如表所示,若分数93的个数为2,则该分数对应的名次为_____________。
(2)请在划线处填入合适的代码。
Dim sName(1 To 50) As String '存放学生姓名
Dim sScore(1 To 50) As Integer '存放学生分数
Dim recCount As Integer '存放学生人数
Private Sub Form_Load()
'本过程从数据库中读取学生数据,存储在相应的变量中,并在List1中显示
'代码略
End Sub
'整数转换成长度固定的字符串
Function ads(x As Integer, n As Integer) As String
Dim sx As String, nx As Integer, i As Integer
sx = Str(x): nx = Len(sx)
For i = 1 To n - nx
sx = " " + sx
Next i
①
End Function
Private Sub Command1_Click()
Dim A(0 To 100) As Integer '存放每个分数的个数
Dim B(0 To 100) As Integer '存放每个分数的名次
Dim mc As Integer, score As Integer, i As Integer
For i = 0 To 100
A(i) = 0
Next i
For i = 1 To recCount '计算每个分数的个数
②
Next i
mc = 1
For i = 100 To 0 Step -1 '计算每个分数的名次
If A(i) <> 0 Then
B(i) = mc
③
End If
Next i
List2.Clear
List2.AddItem " 姓名 分数 名次 "
List2.AddItem " ---------------- "
For i = 1 To recCount
score = sScore(i)
mc = B(sScore(i))
List2.AddItem sName(i) + ads(score, 5) + "第" + ads(mc, 3) + "名"
Next i
End Sub
二 考查知识点桶排序,自定义函数。要求学生熟悉自定义函数的语法特征,并具备根据题目文字说明和样例数据理解算法逻辑的能力。
三解析第一空比较简单,只要结合示例图片看懂注释,明白ads函数的作用,再根据自定义函数的语法特征(函数语句块中必须有一个形如“函数名=表达式”的语句,才能将表达式的计算结果作为函数的返回值传回函数调用处),不难写出答案。
我们结合代码,添加注释分析如下:
高考VB算法题的一个重要特征就是题目会把算法思想完整地呈现给考生,考生只要根据算法分析去理解代码就行了。有时候光看文字说明还不够,需要结合样例数据、图片示例和代码注释才能理解算法逻辑。
首先来理解数组A的含义,数组A用来存储每个分数的个数,其每个元素的下标和值分别对应某个分数和该分数出现的次数,例如,若A(60)=5,则代表有5个学生考了60分;若A(70)=4,则代表有4个学生考了70分。
因此计算每个分数的个数,就是累计数组A中下标为sScore(i)的元素值,这是经典的桶排序思想。
在计算每个分数对应的名次时,先规定最高分为第1名,即初始化mc = 1;然后从高到低遍历每一个分数,设置该分数的名次B(i) = mc;接着更新下一个有效分数的名次mc=A(i)+B(i)。如此循环处理每一个有效分数。
本算法的巧妙之处在于它不是直接存储每个学生的名次,而是存储每个分数对应的名次,最后根据学生成绩输出其名次。这样只需一重循环就可以完成计算,大大提高了效率。 四 答案(1)7
(2)①ads = sx
②A(sscore(i)) = A(sscore(i)) + 1
③mc = A(i) + B(i)或 mc = mc + A(i)
五拓展思考如何使用Python语言来完成这道题目的功能?
描述:根据成绩算名次。已知元组t存储了若干个学生的成绩,成绩为0到100之间的整数。
请编写函数返回各学生的名次,其中最高分为第1名,成绩相同则名次也相同。
要求时间复杂度为O(n),也可以理解成只能使用一重循环。
函数名:ranking(t)
参数表:t -- 存储了学生的成绩的元组。
返回值:返回一个列表,其元素值为相同下标的元素在元组中的排名。
示例:对于元组t = (3,2,2,4,3,5),返回[3,5,5,2,3,1]
六拓展思考答案为了保证解析的原创性和思维的独特性,我都是独立解题后,先不看答案(除非题目不会做),直接把解析写好,再去看答案。
当然,如果发现参考答案有更好的思路,我还是很乐于学习和借鉴的。同时,由于本人水平有限,解析中难免出现疏漏甚至错误之处,敬请谅解。
无论是赞同还是反对我的看法,都请你给我留言。如果你有新的想法,千万不要憋在心里,请发出来大家一起讨论。让我们相互学习,共同进步!
需要本文word版的,可以加入“选考VB算法解析”知识星球参与讨论和下载文件,“选考VB算法解析”知识星球汇集了数量众多的同好,更多有趣的话题在这里讨论,更多有用的资料在这里分享。
我们专注选考VB算法,感兴趣就一起来!
相关优秀文章:
阅读代码和写更好的代码
最有效的学习方式
选考VB算法解析之2017年4月高考真题卷第12题
选考VB算法解析之2017年4月高考真题卷第16题