前言
又到了万众瞩目的我Macw来给大家讲题。感谢x01班的同学们参与本场oi考试,oi赛制的考试确实比ioi赛制的考试要刺激(老师们也感到刺激)。今天的题目一共七道题,难度确实也稍微有点大,但我为你们x01班的所有同学鼓掌,为你们的坚持喝彩。
题目解析 - 商品纪念铺
题目链接:https://www.acgo.cn/problemset/4441/info?teamCode=1664181761155715072。
这道题考查的核心知识点在于同学对数组等线性表的”增删改差“操作。数组是一个很神奇的数据结构,其在内存中是连续分布的,因此对数组来说,删除元素是一个很复杂的事情。虽然本题难度比较大,但可以将一个大问题分解为许多个小问题一一解决,这样子这道题就很好做出来了。
问题一:如何进行数组的初始化操作?
这一个小问题考察的就是学生在数组中存储数据的熟练程度。数组的存储可以使用一个for循环批量的将数据存储下来:
这就完成了第一步操作,是不是非常简单?
问题二:如何进行数组的单点累加操作?
所谓的数组单点累加操作,就是取数组中的m个数,将这m个数相加即可。这个小问题考察的就是学生对数组索引取值的掌握程度。为了获取数组中某一个位置上的值,可以通过索引获得。
例如获取数组中的第一个数字:
因此,我们可以创建一个累加器total,用于记录所有数字的和。代码如下,其中n代表需要累加的数字的数量,t代表每一个累加的数字的索引。
先献上本题的前半部分的代码,到目前为止应该都是很简单的,就是普通的数组操作仅此而已。
接下来难度就要上去了,有请:
问题三:如何将数组的数往前挪一位?
这个问题也比较简单,可以通过一层for循环的方式解决。具体代码如下:
以上代码应该非常好理解,将数组中第i+1个位置的数存到数组中的第i个位置。这样子就能完成将数组中的数往前挪一位的效果。这就是本题的核心难度,本题最难的地方就是如何将数组中所有的数字往前挪一位,如果到这里你都看得懂的话,那么恭喜你这道题对你来说就是小菜一碟了。
问题四:在什么时候需要将数组中的数往前挪一位?
这个问题也很好理解。设想一下在数组中,如果这个数已经被取走了,则后面的数字都需要在数组中往前挪一位。因此问题就被转化成了如何记录一个数字已经被取走了?
事实上,我们可以在每次结束累加arr[i]的操作后将arr[i]的值设置为-1,这样子我们就可以通过遍历arr中的所有值的值哪些数字之后的数字都需要往前挪一位。
前半部分的代码如下:
问题五:当取走K物品后,数组的长度是多少?
一开始,数组的长度为n,代表有n件商品。随着商品被购买走后,n的大小也需要随之减少。那当k件商品被取走了,n的大小是多少呢?答案是n的大小会缩小k,也就是n -= k。也就是说,每次当一个物品被买走后,数组在排序后的长度就是原本长度-1。这个应该很好理解吧。
最后,完整代码如下:
上面这个代码是肖老师的代码,肖老师的代码比较好理解,这边再附上我自己写的官方版本,稍微有点难理解,但是总体的思路都是差不多的。
小彩蛋
在赛后看题目的过程中,我还看到了x01同学给我献上的真挚祝福(大家都挺开心的)。
好了,今天就到此为止吧,祝大家在杭州过得开心,过得快乐!