数学 lover
一般的入门顺序:
- C 语言的基本语法 (或者直接开 C++ 也行,当一个 java 选手可能会更受欢迎,并且以后工作好找,但是难度有点大),【参考书籍:刘汝佳的《算法竞赛入门经典》,C++ 入门可以考虑《c++ primer plus》,java 选手可以考虑《think in java》or 中文版《java 编程思想》,请远离谭浩强...】
可以选择切一些特别水的题巩固以及适应一下 ACM 中常见的输入输出格式... 例如杭电著名的 100 题
- 一些基本算法和数据结构 (队列 栈 树 图 并查集 堆 DFS BFS 最短路 最小生成树 拓扑排序 动态规划 贪心 搜索 KMP 哈希 Trie AC 自动机 快速幂 逆元 费马小定理 欧拉函数 素数筛 分解质因数) 你可以找两个小伙伴一起分工合作,各自认领专题【参考书籍:刘汝佳《算法竞赛入门经典第二版》or《算法竞赛训练手册》,《算法导论》】这时候可以刷的题就多了,你可以选择一些专题进行突破,学习一下技巧 例如
[kuangbin
带你飞] 专题一 简单搜索 [kuangbin
带你飞] 专题四 最短路练习
[kuangbin
带你飞] 专题五 并查集
[kuangbin
带你飞] 专题六 最小生成树
[kuangbin
带你飞] 专题十二 基础 DP1
[kuangbin
带你飞] 专题十四 数论基础
[kuangbin
带你飞] 专题十六 KMP & 扩展 KMP & Manacher
[kuangbin
带你飞] 专题十七 AC 自动机
如果这些你和你的小伙伴都能熟悉掌握,并且能够尽快写出来,那么没有意外的话就可以在网络赛中拿到现场赛的门票(当然还得看出题人的风格...)
- 一些进阶的算法以及复杂一些的数据结构(树状数组 线段树 平衡树 后缀数组 二分图匹配 网络流 费用流 割点 桥 强联通 双联通 最近公共祖先 四大 DP(数位 dp 区间 dp 状压 dp 概率 dp) 博弈论 SG 函数 )
【参考资料:各种博客......】
[kuangbin
带你飞] 专题七 线段树 [kuangbin
带你飞] 专题九 连通图
[kuangbin
带你飞] 专题十 匹配问题
[kuangbin
带你飞] 专题十一 网络流
[kuangbin
带你飞] 专题十五 数位 DP
[kuangbin
带你飞] 专题十八 后缀数组
[kuangbin
带你飞] 专题二十一 概率 & 期望
[kuangbin
带你飞] 专题二十二 区间 DP
这些掌握之后在现场赛中拿到牌子应该就没什么问题了,发挥出色还能拿到银牌。。。不过如果遇到比较凶残的赛区...
2.5 这时候如果开始组队了,就可以去刷一些套题了,例如
这里每一场比赛都是过去真实发生的录像,你可以 clone 之后和自己的队友一起实操一下。
这部分最能体现人与人的差异了... 智商碾压一般就在这部分。而要想拿到金牌,一般来说这些知识都要尽可能掌握。
【参考资料:各种论文,解题报告】
这部分的题目比较杂,因此请自行去 vjudge 上查找....
3.5 同 2.5,并且中国国内的比赛如果已经满足不了你,你可以去
https://icpcarchive.ecs.baylor.edu/index.php
或者
上找到全世界的区域赛的题目,不过题解就不怎么保证了...
也许你会觉得性价比很低,学这么多东西,才 " 有可能” 拿到牌子,但是收获的不一定是物质的牌子,还有学习过程的苦辣酸甜的经历(例如各种 WA TLE RE MLE 之后的一次 AC),还有和基友一起并肩作战切套题的同甘共苦,而且还锻炼了自己的学习能力(善用百度,谷歌,维基百科)。
所以
Good Luck and Have Fun.
=============== 我是 WA 和 AC 之间的分割线 ===============
一言不合就过百赞了,好开心啊~
再补充一下:
这些算法都是说着容易,但是灵活搭配用起来难,然后还能在一定时间内写出来,并顺利通过数据测试拿到 AC 更难。
由于大家手上的模板越来越强大,区域赛一般都不会出现裸的模板题了,一旦出现,肯定就是被大家骂回家的存在。所以在综合训练的过程中,尽量选择需要动脑的题目,不要一昧追求直接贴一个模板上来 AC 走人特别爽的题目。
一般比较需要动脑的题目类型:贪心,动态规划(最好需要加上优化的),组合数学(推组合数公式,各种等价变换),图论(网络流,最短路,匹配)的各种建图过程。。。
虽然说年轻人要少水群,多做题,才能进 Finals——kuangbin
但是一直闭门单刷也不是一件好事,还是要和大家多多交流心得,这样才能避免自己陷入一个瓶颈。
匿名用户
2016.10.20 更新
本人背景:大学之前没有搞过竞赛,天赋一般,今年大三出去比赛,今年(2016)区域赛铜。
经过一段时间的反思,结合自己这两年 ACM 训练就 “请问 ACM 的正确入门方式是什么?” 发表一点拙见
目录
预备知识
基础部分
进阶
做题
训练
杂谈
注:本人对于掌握内容的等级由高到低分为:精通、掌握、了解
0 预备知识
0.1 C++ 基础语法部分
想要入门 ACM,首先你要有一定的编程基础,一般国内的 ACM 选手都是用 C++ 的,所以 C++ 的基本语法你应该有所了解。
0.1.1 库函数的了解
包括但不限于这些库(头文件):基本输入输出 如 cstdio, iostream,以及一些从 C 的库弄过来的像 cstring, cctype,cmath 等库,具体可以随便百度一个人的代码,然后看看他的头文件
0.1.2 基础知识
如 int 的最大值是多少?int 占多少内存?逻辑运算,循环等,不一一赘述。值得一提的是位运算,应当了解电脑中数据的存储方式,很多时候利用位运算帮助做题非常重要,如树状数组的 lowbit,状压 DP,快速幂等,每次我看到这些的时候都深深的感受到二进制的神奇。
0.2 C++ STL
非常有用的 STL 如 algorithm, vector, list, set, stack, queue, map 等,对于 STL 的学习,本人推荐曾棕根老师的这本书《ACM 程序设计》
,建议初学者了解每一个容器都有什么样的方法以及各个方法的时间复杂度。不同的容器利用了不同的数据结构,所以做出相应的操作对于系统的时间开销就大不相同,这点还是挺重要的。原来做一道题,网上看有人用 vector TLE 了,ctrl+f 把所有的 vector 换成 list 就过了。
0.3 Java 基础
个人感觉 Java 并不常用,当然 Java 中的 BigInteger 类(高精度整数)是非常有用的,一般情况下,当别人苦逼的粘贴 C++ 的大数类研究方法的时候,Java 可以十行代码优雅的解决问题,同时建议稍微学习一下 BigDecimal 类。
0.4 时间复杂度和空间复杂度的计算
时间复杂度是一个非常重要的概念,相同的问题,有的人给出的方法需要 1s,有的人给出的方法需要 1h,那必然是 1s 的方案在时间方面更优。
空间复杂度同理,如果空间很大,用不完,可以考虑使用空间换取时间的方式,很多算法都是以这个为前提的。
研究一下为什么很多题给的数据是 10^5?一般题给出时间是 1s,有的给出 2s, 3s 甚至 15s,是否能给你想法上的暗示?空间复杂度同理。
0.5 ACM 中的基本错误
Wrong Answer: 有自己没有注意到的细节,或者方法错了。
TLE: 运行时间超过给出时间
CE:编译错误,可以点进去看
RE:有时候会 stack overflow,access violation 之类的
PE:空格或者回车有问题
1 基础知识
大一的时候一开始就学了二分 / 三分,BFS、DFS 去找迷宫路径,当时只能循规蹈矩的改模版,当时并不懂栈(stack)和队列(queue),每次都要纠结一下是 FIFO 还是 FILO。后来做着做着题,发现,像 BFS、DFS 这种东西,完全就是个思想啊,哪里有什么模版。此时,我大概可以随手写一些深搜、广搜了,但是我对于这些的应用还是不太敏感,只有多做题才能一直提醒自己灵活的运用这些。
所以,上面这段话,我想表达这样一个事情:基础要学好,达到精通的程度,并且要多做题,每一种要做 20 道题左右。(本人训练的时候大概是 10 题的样子,但是感觉并不够,所以建议 20 道)
基础的内容:
BFS、DFS、二分、三分、筛法求素数、快速幂、并查集、矩阵运算及快速幂、最短路相关(Dijkstra, floyd,ford,SPFA)、基础 DP(LIS、LCS、记忆化搜索等)、网络流(EK、Dinic、ISAP+gap)、KMP、线段树、树状数组、二分图、最小生成树(Prim、Kruskal)、计算几何基础等
按照紫书上的来吧,题主看紫书觉得很吃力,其实说实话,我本人看紫书也挺吃力的,建议先从 Vjudge 上找相关专题做,比如高票答案推荐的 kuangbin 带你飞系列的,HDU 的题个人感觉比 UVA 要简单一些。
2. 进阶
这个阶段其实就可以和队友分工搞了,推荐参考白书以及多校训练。
我个人对这个阶段的建议是:一部分内容学会用板子,大概知道板子每一步在干什么,达到了解的程度。一部分内容要掌握原理。如果实在不知道在干什么,就当用黑箱一样去用。就像你知道 cmath 里有 sqrt,但是很多人完全不知道是怎么实现的。
像很多数论的东西,比如 Lucas,你会用模版大概就可以了,这种东西几乎没有什么改的必要,但是了解一下什么时候用 lucas 求组合数,什么时候打表求组合数之类的还是很有必要的,对于不同情形应使用不同的方法。
但是对于像莫比乌斯反演、sg 函数这种东西,经常就需要对于具体情况分析,然后将思想运用到代码中。
还有一些比较中立的,比如 Tarjan 求联通分量的,改的虽然不多,直接用板子,但是可以存储很多信息,如无向图割点、桥,以及对于强联通分量、双联通分量能发挥不同的功能。只能靠做题量去学习姿势。
3. 做题
ACM 我一直觉得非常靠天赋,对于自己这样天赋一般的人,某些选手简直是智商碾压般的存在。后来发现也不尽然,人家天赋高,做一道题付出的时间相对于自己短,相同的时间可以做更多的题,所以强者更强,弱的还是原来的水平。所以,不管你的天赋强弱,多做题吧,付出和收获都是成正比的,天赋的高低的区别只在于将你的收获乘以 0.8 还是乘以 1.2。比如一个天赋很强的人,做了 400 道题,那么相当于一个普通人做了 400 * 1.2 = 480 题的水平,对于天赋差一点的人来讲,就要做 480 / 0.8 = 600 题。大部分人的智商都是差不多的,真正强的人都是做题做出来的,我个人不太相信有谁看一眼 C++ 的语法就能想出来个主席树、莫队算法的,当达到量的高度以后自然会有质的飞跃。BestCoder 上的
,我一天无意间看到了人家在 Vjudge 上的做题量 1748,
。Q 神,BNU 做题量 1715,
。以上两人还仅限于一个平台,并不知道其他平台还有多少题。就我个人而言,只做了 570 题的水平,其中还包括很多水题。听学长说叉姐的做题量大概是五位数,甚至六位数,所以也并不奇怪人家那么强。在普通人智商差不多的情况下,比赛时金银铜大概都是按做题量分配的,这种大家都喝了无数碗的鸡汤,咱们再干一碗。
回到正题,打开 ACM 的正确方式:
刷题,BestCoder 开了有几十场了,CodeForces 有几百场,你做了多少了?
4. 训练
个人的意志力太薄弱,如果有机会的话还是组队训练吧。有组织的训练至少有竞争,有压力。赛后尽可能的 AK 比赛的题,当时我平时训练的时候没有 ak,现在回想起来,陷入了不会,下次遇到还不会,再遇到还不会的循环。
组队的话尽可能强强联手吧,大家合作拿一个大奖才是最好的结果。当队友心猿意马的时候确实挺让人泄气的,举个杭电某队的例子。
G 题因为题意问题,加上我太蠢没有学会潜在坑点分析 + 脑补。
加上 B 题我没有担当起责任,没有解放队友,导致最终打了个铜。
主要原因还是自己太弱。
争取在上海的时候拿个金,至少正常水平发挥拿到 ECfinal 参赛权。
队友一个进过 WF
没了干劲,另外一个想要找工作,也没了热情。虽然他们水平很厉害,但希望在明年,能够不再和”
马上打比赛的时候嘴里却喊着退役,什么结果都无所谓的人”
组队,消极的队友,会带给你一种无力感,真的很累很累。其实还不如单挑,虽然名次会变低,但是至少充满斗志和热情。
5. 杂谈
- 善用搜索引擎吧,有时候 Google 和百度搜出来的题解不一样,虽然我也不知道他们是怎么排名的。看别人的代码总会发现新姿势。在这里推荐一个利益无关的搜索引擎:
写写题解,整理个自己的模版,其实别人能搜到自己的题解和模版,感觉还是挺开心的
别自欺欺人的拿天赋说事了,以绝大部分人努力程度之低,完全到不了拼天赋的地步。沉下心,踏踏实实的学,把紫书白书好好看,做足够量的 BC/CF 题。
只有自己足够强,才能和足够强的人组队,才能比赛拿牌
高票答案谈到性价比,其实我自己也不知道 ACM 的性价比怎么样,但是大学里,有个事做总是好的吧?
原来在网上看到过一篇
,供大家参考
每次查题解的时候总可以看到两句话,无耻的摘录了
“每一次 AC 都是一次感动” 这个似乎是一个 CSDN 博主的名字
"人一我百!人十我万!永不放弃~~~ 怀着自信的心,去追逐梦想。" --kuangbin
鄙人水平有限,如有不对的地方还望各位大牛批评指正。
P.S. 被收藏了 60 多次,只有 30 来个赞,如果有用的话请点个赞呗?^^
rush
在 icpc 中一定要记住,思维能力和直觉是 acm 能力的核心驱动力,在思维能力达到一定层次以后,算法的学习能力也自然而然上来。
1、快速将语法过关,学习基础算法,如单调栈,dp,树形 dp,dfs,lca,lis,二分,基础图论,整除,取余,尺取,贪心,凸包,逆元等,可以上洛谷官方题单板刷,然后去刷 hdu 入门题,也可以去 acwing 刷刷基础
2、打开 codeforces,千万不要没听过就害怕!只要尝试去做几道题,就会不断收益良多!!!在 problemset 里选 1000 到 1600 级别题中找到适合自己难度的题,可以二分查找 (check 是 30 分钟内能否独立查出),最好选择 contrustive(构造)对思维提高最大,然后看看能不能 30 分钟独立推理出来,一定要独立思考,不要觉得怎么也想不到就觉得受挫,也不要看题解!在怎么也想不到的情况下寻找一条路是锻炼直觉的关键,这种想不到却依旧得去想的经历也是直觉提高的重要铺垫!(除非你是天才),不断去做,如果连续五次在 30 分钟内想出这个级别题,就去做这个级别题 + 100 难度的题,然后坚持想 30 分钟,在想的过程中不断寻找可能的方向,想不出来看题解,有不知道的小技巧,小坑点都要记下来,有不懂的算法或特殊应用可以学会,用这种方法不断把上限提高到 2100.
3、经常打洛谷,牛客,atcoder 和 loj 的比赛,偶尔打 codeforces 比赛 (毕竟对身体不好),不断验证自己的实力,而且打线上比赛很重要的是能提高竞赛能力,同时把比赛中会踩的坑都踩了,一定要打 80 场以上!之后就可以只作为验证实力提高的标准了
4、上限提高到 2100 以后,可以开始板刷 atcoder 的 regular contest 了(arc),先板刷 arc 的 c,倒着刷,从最新的刷到旧的 contest,独立思考,不断想办法找方向,找结论,要想两个小时最好!可能也想不出来,刷完刷 d,一定会感到酣畅淋漓
5、然后用 2 的方法回去板刷 codeforces 的 2200 到 2400 级别题,如果有志同道合的队友可以开始分块分专题了,然后去洛谷找相关专题题单,努力刷紫题黑题,每个小知识点刷个 20 题,还有省选题 (bzoj)
6、然后就到了灵机一动的压轴题提高了,狂刷板刷 arc,agc,再刷 codeforces 的 2500 + 题,经常刷 gym,刷毛营,刷这两年的线上比赛,对标国内强队,刷五个小时 gym 能切实提高长期比赛的实战能力,一定要对名次有要求,甚至可以 8 小时连打两场比赛这样来训练,长期坚持比赛能力一定能大幅提高,可以板刷 sgu,有经典毒瘤题
7、参加国内各种 camp,要求名次
答主是个没有实现梦想的银首败犬,希望喜欢 acmer 且看到文章的同学不要留下我这样的遗憾 qwq