3.2.1 为什么要选择 ACM—— 谈谈我与 ACM
author:wenjing
先验条件:保证你可以在每天进行练习和学习此方面内容即使是假期也不能超过三天以上休息,如果你想验证一下这件事当然也可以,注意心态的保持很重要
将时间花在 ACM 上值得吗?
初入大学,摆脱了高中的种种束缚,同学们想必对大学生活有着种种幻想。或许有同学依旧保持着高中的思维,希望刷取高绩点,用好成绩谋求保研。或许也有同学只想将课程草草应付,去探索一些偏实践的方向以谋求一份好工作。
但无论你渴望从大学生活谋求何物,我认为做为一位计算机专业的学生投身于 ACM 算法竞赛学习都是值得,无论你是否得奖。
ACM 能为我带来什么?
显然,做为一名计算机专业的学生,编程是一项必须掌握的技能。再次引用 Niklaus Emil Wirth 的一句话:** 程序 = 算法 + 数据结构。** 例如在大一开设的程序设计基础中,我们需要重点学习链表这一数据结构,熟悉运用分支与循环结构(勉强也算算法吧)。然而,在 ACM 中,这是基础到不值一提的事物,宛如空气与水一般基础。你们是否想过,花了大量课时学习的这些知识,其实小学生也可以学会(看看远处的小学编程补习班吧,家人们)那做为大学生去学习这些知识,是否应当得到一些不止于考试内容的知识呢?
我认为有两个方向,一是我们去学习一些更底层的逻辑与原理,此外就是学习如何更好的利用链表,实现一些别的数据结构做不到的事情,我认为 ACM 可以极大的提升我们对后者的理解。
再从功利的角度而言,我认为学习 ACM 有以下好处
① 你在学习的过程中提前学习了大量接下来课堂中反复强调的知识,所有的编程对你而言都是水课,只要考试前应付一下那远离实践意义的考题即可
② 在招聘面试过程中,考官会问你一些短小精悍的算法题,为了应付这些算法题,你迟早要去刷 leetcode(力扣),做算法题是迟早的事。并且假若竞赛获奖的经历,也可以丰富简历
③ 假如你有幸活过筛选,并且获得比赛机会,并且得奖,恭喜你,你的绩点将被画上浓墨重彩的一笔。做为大学顶尖赛事,ACM 的奖项可以直接在你的最终绩点上加分(铜 0.5,银 1.0,金 1.5)这意味着你只要主课不要落下太多,奖学金随便拿(比赛获奖本身还有额外奖金)。
零基础学习 ACM 是否过于困难?
我并不这么觉得,原因如下
①ACM 前期更看重你的思维能力而不是代码能力,很多题你可能需要很多纸上的推演,但最后代码可能只有十几行,到冲击金牌的阶段需要思维与码力齐驱,但那太远了。
固然,码力需要大量的练习,零基础尤其是第一次接触编程的同学会感到困难,但在度过初期后,限制你写题水平的是你的思维水平,而思维水平就看个人的悟性和理解,这点有无基础我并不认为很重要
②ACM 的刘教练对零基础有特别关照,每次选集训队队员都会固定留下一定量的零基础队员,这意味在名额竞争中,你们大概率并不需要和有基础的同学直接竞争(显然也存在零基础同学更强的例子),而是与其他同为零基础的同学竞争
③ 在初高中参加竞赛的学生的数量和质量有极可能已经有所下降,因为竞赛相关政策的紧缩,稀烂的强基计划替代了对竞赛友好的自主招生,选择全力投身竞赛,拼搏省队的学生有所下降,有基础的学生现在也不见得很强。
UPD at 2023/7/19:从长期来看,这个结论应该是没有错的,但是很可惜,如果您是 2023 届的新生,您将遭遇紧缩政策下一波不得不来 hdu 的竞赛高材生,截至笔者更新为止,已经有五位 NOI 银牌选手和两位具备 NOI 银牌能力的选手提前加入了集训队,也许对于零基础的同学而言,仍然只要和别的零基础同学竞争保底的三个席位就好了。但从长远来看,进队不是结束,抢夺比赛机会才是开始。而且如果 hdu 能抢到这样的生源,其他学校的水平大概率也会上涨,就算有了比赛机会也很难说会不会拿铜遗憾结尾。如果您出于好奇,想了解这荒谬的景象是如何诞生,请参阅电子书《整型溢出》
进队的学生零基础偏少,如果你选择这条路你可能需要克服不小的困难
我应该以什么态度学习 ACM?
假如你是一位有信息竞赛基础,且得过省级奖项的前 oier,您也没什么必要看这篇文章,您已经完全熟悉了算法竞赛需要的一切,我希望您不要有太大压力,做最好的自己就行,不要留下遗憾。对于零基础的同学也一样,或许得奖后的绩点加成实在是过于诱人,但竞赛获奖这种事情还是太难强求,让自己压力太大得不偿失。
这里我想谈谈我的经历,我从初中开始学习算法竞赛,一开始只是抱着试试看的心态,结果发现自己还过的去,获得普及组一等奖,便继续学习去冲击一等了。
转折点在初二下的暑假,当时特长生这一机制仍旧活跃存在,只要拿到提高组一等奖或者分数在一等线附近,你就有机会无视中考成绩上一所好高中,于是我从这个暑假开始就几乎再也没有回到过初中(除了最后一个月,因为学校不希望我分数太低拉低平均分影响招生,虽然分数对我而言根本无所谓)这也成为我很大的一个遗憾,关键一年的缺失使我几乎与初中的同学到现在不存在任何感情纽带,名字也不记得几个了。
转回正题,封闭式的竞赛集训让我感到无比痛苦,一边是升学的巨大压力,竞赛比起中考存在着更多偶然性,倘若在十一月的比赛中失误,我将前功尽弃,用于竞赛的时间毫无意义,文化课也将因此与其他同学拉开差距;另一边是同一届的神仙太多,我能走到集训这一步也许已经比很多人优秀,但和那些” 神 “比起来还是差太多,能力上难以填平的鸿沟与青春期的烦恼让我活的浑浑噩噩。
如果不出意外的话,我的人生就要出意外了。在那一年的 NOIP(信息学竞赛省赛)中,我在 DAY1 取得了满分的好成绩,于是我飘了,我在做一个梦,我真的不如那些” 神 “吗,我是否也可以做到更多?于是我 DAY2 死磕难题,分数爆炸了,最终差五分够到一等线。
之后的日子是灰暗的,浑浑噩噩的训练,知难而退放弃最好的高中的特长生名额。故事很长,我只是想说学竞赛不要太功利,竞赛终究是少数高手的游戏,做不到就是做不到,但这也仅仅只代表你的竞赛能力不够,你的人生并不是只有竞赛,大学也不只有 ACM 一条路(这很显然,不然我们社团应该改名为 ACM 社)
再谈 ACM 为我带来什么
我初中成绩并不差,但发挥失常的话确实上不了我毕业的高中。我高考发挥失常,竞赛通过杭电三一成为保底。
但倘若说存在一个一开始就没有学过竞赛的我,我是否在考试分数上会有更高的成就呢?可惜人生没有如果。
进入大学,再次拾起算法竞赛,这次,我并不觉得惶恐与焦虑,因为无论是否得奖,我享受研究算法的过程,欢喜于做出难题带来的成就感,我在愉悦的学习,这样就够了。
我在说的不止 ACM 能为我们带来什么,我也在说学习能为我们带来什么。或许,考试只是给我们一个去学习的借口;或许,考试周的应试复习只是生活中无可避免的无意义之事。需要应付的无意义事物总是存在,你不能保证自己的每分每秒都被投入于黄金般的事业中。如果学习 ACM 让你感到有趣,那就去学,不需要别的理由。
截止完成这篇文章为止,笔者仍在集训队中,我害怕自己被淘汰,不是因为我害怕自己失去参赛资格,而是我很难想象自己失去 ACM 的生活,我需要一个学习 ACM 的理由。给诸位讲个笑话,某一天我与朋友出门游玩,想不到话题,于是就开始讨论算法题的做法,从正午到日落。
算法思维与应试思维
众所周知,ACM 是开卷竞赛,你可以携带纸质资料进入考场。
这时可能就会有同学特别开心,哎呀,这不就是开卷考试嘛,我平时程设期末考试都不能开卷,这开卷了还不简单,我直接对着书抄抄抄不就好了。
熟悉编程的朋友可能知道,有一个词叫做” 模块化编程 “,这意味着你将程序的功能拆解,让你的主函数由一个个定义好的函数组成。
同样,在你对 acm 题面进行转换后,问题可以被拆成一个个小模块。例如我现在要对某个数组进行排序,其实我根本不用知道排序算法是怎么进行的,我只要从纸质资料上扒一段代码就行。
但是,假如你一直依赖这些现成的代码,不思考算法的内核,仅仅把他们看做一个个提供输入输出映射关系的” 黑箱 “,ACM 会容许你这样生搬硬套,死记硬背的选手占上风吗?不见得。
首先对于更高层次的题目,为了防止重题,直接套板子基本是不可行的,你需要对一些代码进行优化和调整。倘若你把代码看作一个个黑箱,又该如何去调整他呢?
其次,将一个算法学的透彻,对我们的算法思维大有裨益。
比如大家以后耳熟能详的快速排序,他的思维可以实现 O(n)求出第 k 大的数;而归并排序的思维不仅可以用于大量分治问题,例如其衍生算法 cdq 分治,其合并区间的思想也可以用于线段树。
只会抄板子的选手能理解这些吗?假如我们对代码死记硬背,生搬硬套,我们的知识体系就是离散化的,缺少关联的。不利于我们今后的发展。
也许在一次次陈旧腐朽的选拔性考试中,应试思维取得了压倒性的胜利。但在 ACM 中,算法思维依旧有一片净土。
数学与算法思维
那么,如何培养算法思维呢?我认为首先我们得学好数学。然而,我最总是在大一中听到这样的声音:“哎呀,烦死了,我们是学编程的,为什么要花那么多精力学数学,还占那么多学分,真讨厌。“然而,比起枯燥乏味的编程课,我最喜欢的还是数学课。数学在算法中无处不体现,可以说学好算法就是要学好数学,我现在复盘我初中 OI 生涯的失败,很大程度归因于数学基础的薄弱。以下为几个体现数学在算法中重要性的例子。
① 众所周知,ACM 是组队比赛,比起国内三个狂战士无需分工嗯干,国外有较为成熟的组队合作机制。一般由一位擅长开题拆解题意转换模型的队员,一位码力超群擅长高级数据结构的队员,剩下一位,则会跨专业选取一位数学系的学生,由此可见数学的重要性。
② 计算机中有大量的算法直接运用了数学,例如,快速幂的正确性需要数学推导,利用快速幂求乘法逆元也直接用到了费马大定理。
③ 计算机算法本就是数学的一部分,翻开计算机学生必修课程离散数学的课本,你会发现图论中的最短路算法,甚至网络流算法,都是离散数学的一部分。
④ 获奖的 ACM 队员就没有数学差的。
现如今,学科与学科之间并不是的独立的,数学系的学生也会学习编程,去解决一些算法问题,例如我们学校理学院的一位老师就有在做算法理论方向的研究。
反过来说,计算机的学生也可以好好学习数学,加深对算法的理解。哪怕以后去从事热门的人工智能方向,数据处理、卷积(虽然此卷积非彼卷积)、反向传播、感知机、神经网络等知识点都离不开数学。
优秀的数学思维能使你在理解算法的路上事半功倍,当然,算法的学习也能加深你对数学的理解。
结论
大胆去学 ACM 吧,大一的空闲时间真的很多,去探索新事物,不试试怎么知道自己行不行。