FAQ
集训队相关
协会和集训队有什么区别?
我们学校有 ACM 协会和 ACM 集训队两个组织,大家可能分不清。
ACM 集训队更偏向竞赛学习,队内会组织算法训练,并选拔队员参与国家级、省级比赛,也负责校赛的出题。
ACM 协会是一个社团,更偏向于向同学们普及算法,会组织算法助学课,筹办校赛,维护协会公众号等。
没有编程基础怎么办,进入集训队很难吗?
我们学校基本没人有 OI 经历,最高可能是提高省二,可能会领先大家一点。集训队 90% 以上都是完全的零基础,甚至有很多同学高中没选技术,大家都是同一起跑线。
如果是其他专业的也不用担心,ACM 只需要一些 C 的语法基础即可上手。即便上过算法课的计算机专业同学,在没有经过专门训练的情况下,在算法竞赛上一定是不会比你强的。
ACM 里面数学相关的内容占据了半壁江山(数论、组合数学、计算几何、多项式、动态规划……),很多题目都需要进行大量的推式子,因此数学好的人来 ACM 是很吃香的。数学不好也没关系,一队三个人,还有和数学无关的半壁江山。
学习相关
算法太难了,我连最简单的 DP/01 背包都学不明白
节选自 谈ACM生涯总结的经验 - 黄磊。
对于我们普通人来说,这几乎是必然遇到的问题了。但他其实并不如你想象的难,万事开头难在这里形容的恰到好处。同时,很多专题往往开始是一些比较简单的模板题,稍微做几题就会上升到铜牌/银牌题的水平了。
对于一个刚入门的初学者来说,一下子遇到这些充斥着思维的题实在是太难了。我当初也是靠对着题解一行一行敲代码来的(尽管这没什么用),DP 的状态转移公式怎么看都看不明白——但是总有一天,你在过了一段时间再回过头来看它的时候,会觉得恍然大悟,会突然明白 DP 原来是这么一回事情。
为什么用 C++,我用 Python 行不行?
几乎所有比赛都可以使用 Java、Python 和 C/C++,但主流是 C/C++。刷题网站支持的语言很多,有 NodeJS、Rust、Kotlin、Go、Haskell 等几十种语言,你会的不会的都有。
建议入门前学好 C,入门后用 C++(其实还是 C with STL,用不到多少 C++ 特性)。计算机在大二上会有一门 C++ 课程,不如提早学好。
为了比较大家设计的算法的优劣,需要比较程序空间和时间的使用情况。因此我们最好使用更底层的语言,以更深入掌控指令,提高硬件的利用效率;同时又不能太底层,否则会不太易用。基本上符合的只有 C++ 了。
假如你选择非主流的语言,比如 Java/Python 等,你会遇到很多困难:
- 网上的算法资料都是 C++ 的,几乎没有其他语言,连个交流的人都没有,你只能自己摸索。
- 其他语言的效率不高,一般题目时空限制会放宽到 C/C++ 的两倍。但基本上还是无法通过,因为太慢了。
为什么 Java/Python 效率不高
如何编写高性能的 Java/Python 代码是一门很深的学问。但在比赛环境中,你基本用不出来。
Java 因为 JVM 的原因,启动慢了一截(只有 LeetCode 会剔除),而且对象属于 Reference 类型,大量使用了指针,空间和时间上都有很大的劣势。在只用基本类型的情况下与 C++ 性能还是比较接近的。
Python 抽象程度更高,代码显得优雅且简洁实用,但是由于高度动态的解释特性,性能有很大的问题。官方解释器 CPython 不像 Java 有 JIT(即时编译)技术,运行效率非常低下,比 C++ 慢 5 到 100 倍不止。因此在竞赛中大多使用 PyPy,JIT 优化能够显著的提升速度,但是效率仍远低于 Java。你可能会在内存达不到限制时埋怨解释器:为什么数组 [True, True]
需要 80 字节的内存?
其他语言正式比赛支持较少,只能闲暇时在刷题网站上交着玩了。
其他
为什么要做一个 Wiki?
因为网上的资料过于杂乱,我希望能整理一些更有可读性的文章,让资料更有价值,让知识更有序。
也有很多大型项目在干同样的事情,如 OI-Wiki,虽然文章质量很高但是并不容易读懂(我太菜了)。毕竟大学才开始接触编程,需要更低的门槛。
我更期望这里文档具有线性可读性,能够像一本书一样顺序的学习。