我不是特别了解你的水平。不过如果你刚刚大一,已经将我的《算法与数据结构》《玩转数据结构》两门课程学习完了,并且整体掌握了,应该基础已经相当好了,肯定已经超过99%的同龄计算机专业的同学:)
不过,在这里,我必须给你泼一盆冷水。那就是,对于参加acm竞赛,我的课程是远远不够的。只掌握我的课程的内容,可能连区域赛都打不进去。毕竟我的课程是以“面试”为基准线设计的。而面试算法和竞赛算法,差着十万八千里。做竞赛,就是和剩下的那1%,甚至是0.1%,0.01%的同学比拼。
具体路线上,由于acm本身所涉猎的知识实在是太广了,很难以主次先后的方式把所有知识点做成一本“教材”,叫做“玩转算法竞赛”,这近乎不可能。所以,在这里,我只是提一个大概,在具体路径的实施上,需要你根据自己的实际情况,进行调整。
1
我的《算法与数据结构》《玩转数据结构》两门课程,强调经典算法和数据结构的底层实现。但讲真,对于竞赛,很少考察这些。不是因为这些多简单,而是因为这些内容现在竞赛的形式很难考察(而面试的形式却很容易)。所以,你几乎不会简单在竞赛中需要你从底层实现一个排序算法或者一棵红黑树的。竞赛算法方面,最重要的其实是算法设计能力(以及经典算法和数据结构的应用)。我的《玩转算法面试》课程(https://coding.imooc.com/class/82.html ),主要是以Leetcode题库为纲,介绍的这方面知识。有兴趣可以参考。但依然是,我的课程面向面试,所以同样的主题,竞赛的题目可以难上100倍:)
2
对于竞赛,一个重要的需要补充学习的内容,是数学,更准确的说,是离散数学。我不确定你现在在学校有没有学习离散数学。不管有没有学习,都可以学习起来。依然是,算法竞赛中的问题对离散数学的要求和一般学校学习的离散数学的水准相差甚远(也视你的学校水平而定。比如北大的离散,确实不简单。)但不管怎样,如果对离散数学所涉及的内容没有一个整体认识的话,可以随便找一本离散课本,先学习起来。
离散数学本身也是一个大篮子,整体,对于算法竞赛来说,对于组合数学,数论,图论,群论,离散优化,计算几何,等等领域,都有所涉及。如果你整体对一般《离散数学》所涵盖的内容已经有了一般性的认识,可以再根据自己的实际情况,具体去某一个具体领域再学习。
另外一个我想提一下的是,传统人工智能的方法,对竞赛也有帮助(启发式搜索,A*,模拟退火,遗传算法,等等等等)。。可以根据自己的情况看是否要学习。一般不太差的学校,大三的课程会涉及这些内容。
3
在学习的过程中,对于准备竞赛来说,没什么捷径,剩下的就是刷题了。依然是,我不确定你的水平,但鉴于你刚刚大一,并且提出了这个问题,我从最低的level开始说。
我的建议是,从Leetcode刷起。Leetcode上的问题虽然面向面试,但是我个人认为作为算法竞赛入门,挺合适。不要看不起。Leetcode每周有周赛,1个半小时4道题,有兴趣可以参加。从竞赛的角度,如果做Leetcode的问题达到:中等问题一般不在话下,那么就必须向更高级的题库进军了。
对于面向算法竞赛的平台,现在其实已经很多了。整体而言,我个人觉得都ok,差别没那么大。但是我个人比较推崇CodeForces和CodeChef两个平台。这两个平台我就不具体介绍了。你做acm应该都知道。这两个平台的竞赛都比较多,跟着练就行。每次练习以后,不懂的问题想办法去搞懂。根据我的经验,一场比赛n道题,如果你做出来了x道题,比赛后通过学习讨论交流看题解,再多做出来2道题是没有问题的。每场比赛都这样滚动,水平就慢慢上来了。当然,其实平台无所谓,刷题,找到自己知识或者应用的盲区,不断进步,就好了:)
通过上面的叙述,你也应该能看到,如果想取的好成绩,学习的东西很多,练得东西也很多。要平衡好。大把的时间付出是不可避免的。因为所有的竞赛都是如此,从游戏竞赛,到体育竞赛,比拼的都已经不是“一般性的了解”了,而是精益求精。不过依然是,如果你刚刚大一,已经掌握了我的两门课程的内容,已经很了不起了。前途无量,继续加油!