2022 年
作者 21级cy 及 群内各成员集思广益贡献的代码;修改 20-软工-高歌
测试用例:
解:第一题依然是一道不能更简单的基础题,没什么好说的。
测试用例:
解:依然是一道没什么难度的题目。按最基本的思路,可以写出下面这样的代码:
虽然上面的代码很明显没什么问题,也显然能拿全分,但你也可以考虑优化一下:
然后是喜闻乐见的一行流代码:
如果你真喜欢写一行流可以注意一下,列表推导式很多时候可以换成生成器推导式(用圆括号包裹),这样更省空间,然后作为函数参数的生成器推导式还可以进一步省略其两边的圆括号,就像上面的代码不用写成
sum((1 for i in range(n, m + 1) if 100 <= i < 1000 and i % 2 == 1))
或sum([1 for i in range(n, m + 1) if 100 <= i < 1000 and i % 2 == 1])
。已知一个正整数集合,如果将其中的数按从小到大的顺序排列,是缺失一个数的等比数列。请求出这个缺失的值。
测试用例:
解:这道题显然就是 2021 年的第 8 题换个皮,思路也是一致的:
给定一个由大小写字母组成的驼峰字符串,求驼峰高度的最大值。其中驼峰字符串由小写字母开始与结束,小写与大写字母间隔出现,例如 aBa,xYa, eRdHp。驼峰高度根据三个相邻的字母(即小写大写小写)进行计算:中间大写字母 ASCII 码值分别减左右两边小写字母的 ASCII 码值,然后取绝对值,绝对值大的即为该峰的高度。计算所有峰高,并返回最大值。举例,eRdHp 有两个峰 eRd 与 dHp,其中 eRd 的峰高为 max(19, 18)=19, dHp 的峰高为 max(28, 40)=40,因此整个字符串的驼峰高度最大值是 40。
测试用例:
解:一道看着复杂其实做起来非常简单的题目,照着题目直接写就行。
给定一个由整数组成的列表,对其进行排序。排序的依据是:根据整数的出现次数降序排序,如果两个整数的出现次数相同,那么根据整数的大小升序排序。
测试用例:
解:年年都会考的排序题,这一年也没什么特别的。
测试用例:
解:也是很容易考到的矩阵题了,这道题用不到什么复杂的算法,还是挺简单的。下面是一种做法。做法有很多,不用局限于这里给出的一种。
测试用例:
解:有一定难度的算法题,应该可以说是三年中最难的一道题了。这道题考察的应该是对动态规划的应用,此外这道题用小顶堆做起来也非常方便,但本意应该还是考察动态规划。
和往年的压轴题类似,这道题也是 LeetCode 的中等题,而且是那种广为流传的经典算法题,一般不叫作“冠数”而叫作“丑数”。不过这道题在 LeetCode 第 264 题,刷题不太勤快的同学可能碰不到。
这道题最重要的一点是要发现冠数一定是由冠数乘以 2、3、5 得到的。如果这点都没发现,你可能只能写出类似下面这样的暴力程序:
上面的代码显然只能得少部分分。但如果你发现了上面提到的规律“冠数一定是由冠数乘以 2、3、5 得到的”,那么可以对代码进行一些优化:
上面的代码就可以得到一半分了。到这里为止,还不算太难。(注:有些同学可能会认为这里使用的
in
是 O(n)的,然而实际上由于集合是使用字典实现的,而字典的in
是 O(1)的,因此集合的in
也是 O(1)的,在这里这几个in
不会对时间复杂度产生太大影响)然而如果你稍微聪明一点,就可以发现你不需要一个数字一个数字这样试。为什么不每次选择最小的一个数,并将它乘以 2、3、5 然后添加到集合中呢?
从理论上来说,上面的代码是得不到满分的,毕竟它还保留着一个 O(n)的
min
操作。但事实是这代码真能得满分,可能还是测试用例太水了。没学过数据结构和算法的极限也就到这里了。下面给出使用动态规划的做法:
使用动态规划的一直是这样,代码很简单但思路不太容易想到,这里解释一下上面代码的思路(引自 LeetCode 第 264 题 zzxn 的题解)。
pi 是有资格同 i 相乘的最小冠数的位置。举例来说,一开始冠数只有{1},1 可以同 2、3、5 相乘,取最小的 1×2=2 添加到序列中。
现在冠数有{1, 2},因为 1 已经和 2 相乘过了,因此不用再算 1×2 了,因此 1 失去了和 2 相乘的资格,于是 p2 变成了 2,现在 1 有和 3、5 相乘的资格,2 有和 2、3、5 相乘的资格,但 2×3 和 2×5 没有必要比较,因为有更小的 1 可以和 3、5 相乘,所以只需要比较 1×3、1×5、2×2。
依次类推,每次分别比较有资格同 2、3、5 相乘的最小冠数,选择最小的那个最为下一个冠数,假设选择到的冠数是同 i(i=2/3/5)相乘得到的,所以它失去了同 i 相乘的资格,于是使对应的 pi += 1,让 pi 指向下一个冠数即可。
此外还有个经典的使用最小堆的写法,如果你学过最小堆应该能很容易想到。这也是个可以得全分的思路:
按照 2022 年的情况来看,导入 heapq 模块并没有扣分。但如果你想保险一些,可以直接用 list 模拟最小堆:
当然,堆毕竟是数据结构范畴的知识,理论上来说转专业考试不至于考到这个,出题老师的意思应该更多还是倾向于动态规划。
测试用例:
解:虽然这也不算一道简单题,但比起第 7 题,确实要简单不少。思路很多。
最简单的思路就是一个一个试:
如果你聪明点可以发现,这个 7 和 0 组成的数字本质上就是个把 1 换成 7 的二进制,这样做更快一点:
当然,上面两种思路都能得满分。就算你拿字符串拼接得到这个数字,应该也能得满分,问题不是很大。至于二进制的这种写法,想不到也无所谓,都能做。
总结
2022 年的题目总体上是按照难度从小到大排列的。其中前六题应当没有什么问题,也没涉及什么算法知识,同样也没有容易丢分的点。难度主要集中在最后两题,其中第 7 题比第 8 题更难,而第 8 题应该是比较容易得满分的。
除第 7 题外,整张卷子没有任何地方需要用到数据结构和算法的知识,也没考到正则表达式。第 7 题虽然比较困难,但想出个最简单的暴力解法还是很容易的,即使暴力按 4 分算,这张卷子也就扣个 6 分而已。因此从理论上说,这张卷子的编程题扣分应当和前两年在同一水准。
这张卷子整体让人感觉偏难主要还是第 7 题带来的,而后两题的时间限制是 2022 年新加的,这也给人一定的心理压力(虽然第 8 题的时间限制其实没啥意义,因为几乎不可能超过这个时间)。
一如既往,第 7 题涉及了往年的卷子中也很常用的算法动态规划,这道题的区别在于纯暴力做几乎不可能得到全分,而且需要发现一定的规律(冠数必然是其它冠数乘以 2、3、5)。这确实反映了这几年来转专业考试的难度在逐渐增大。
事实上在 2022 年之前这份指南中还说“不用学任何算法也能拿全分,尤其是数据结构”,但 2022 年的考试表明有时候学点数据结构做起来反而简单,比如这次第 7 题如果学过最小堆很容易想到怎么写,而动态规划的思路不那么好想。因此目前来说,是建议适当学点数据结构与算法的,毕竟谁也不知道未来的转专业考试是否会越来越难。
最后更新于