一、ACM竞赛介绍及规则8 {* E5 R" Q4 Q7 z2 w
ACM/ICPC(国际大学生程序设计竞赛)是由ACM(Association for Computing Machinery,美国计算机协会)组织的年度性竞赛,始于1970年,是全球大学生计算机程序能力竞赛活动中最有影响的一项赛事。ACM/ICPC采用赛区选拔的方式产生参加世界决赛学校的资格, 2001年,来自全球超过25个地区1141所大学的2362支队伍参加了第26届ACM/ICPC的赛区竞赛。在2002年3月,来自世界各地的约60支队伍,200多名选手参加了夏威夷总决赛的角逐。可以说,ACM国际大学生程序设计竞赛是参赛选手展示计算机才华的广阔舞台,是著名大学计算机教育成果的直接体现,是信息企业与世界顶尖计算机人才对话的最好机会。在过去十几年中,世界著名信息企业APPLE、AT&T、MICROSOFT和IBM分别担任了竞赛的赞助商。中国大陆高校从1996年开始参加ACM/ICPC亚洲预赛,前五届ACM/ICPC亚洲区选拔赛在上海设有赛区,由上海大学主办。2002年,第六届ACM/ICPC亚洲预赛将该在北京设赛区,由清华大学主办。本次竞赛将于2002年10月在清华园拉开帷幕,预计将有超过60所国内外著名大学的上百支队伍参加本次竞赛(这也是北京工业大学首次参加此项赛事)。 $ m* }+ M$ |, |; q" r 0 @, Z9 v; O- Q2 yACM竞赛规定,教练是参赛队伍所代表学校的正式教师,每支队伍最多由三名参赛队员组成,每支队伍中至少有两名参赛队员必须是未取得学士学位或同等学历的学生,取得学士学位超过两年,或进行研究生学习超过两年的学生不符合参赛队员的资格,任何参加过两次决赛的学生不得参加地区预赛或者世界决赛。, @7 X3 m% Z: u- V% Y
' R' m3 W9 ]2 N
竞赛中至少命题6题,至多命题10题,比赛时间为5个小时,参赛队员可以携带诸如书、手册、程序清单等参考资料,试题的解答提交裁判称为运行,每一次运行会被判为正确或者错误,判决结果会及时通知参赛队伍,正确解答中等数量及中等数量以上试题的队伍会根据解题数目进行排名,解题数在中等数量以下的队伍会得到确认但不会进行排名,在决定获奖和参加世界决赛的队伍时,如果多支队伍解题数量相同,则根据总用时加上惩罚时间进行排名,总用时和惩罚时间由每道解答正确的试题的用时加上惩罚时间而成。每道试题用时将从竞赛开始到试题解答被判定为正确为止,期间每一次错误的运行将被加罚20分钟时间,未正确解答的试题不记时,地区预赛可以使用的语言包括C/C++和Java,每支队伍使用一台计算机,所有队伍使用计算机的规格配置完全相同。(竞赛具体的软件环境可能根据赞助商的变化而变) V8 }* m- G' h q* B( } 1 ?& R k2 b, Y, M$ Y2 f- E二、关于竞赛的题型分析 d9 p" X1 Y% D5 X2 d/ q! v# THal Burch通过在1999年春季的分析得出了这样的结论,竞赛的程序设计一般只有16种类型,它们分别是:* v! Z$ G, B1 z. }" Y, Z3 i& [
6 Q; K( P- _1 V$ } f: \5 ?; w0 P: X* xDynamic Programming (动态规划) 3 A$ B0 y6 n$ G F+ N& @Greedy (贪心算法) ; D1 g) B' R; x7 Y0 ` i7 wComplete Search (穷举搜索) * J0 u3 s$ B W2 ?5 L' J% Q- |Flood Fill (不知该如何翻译) + O4 p, y* x+ O6 L- ^: V) j
Shortest Path (最短路径) 7 D% g" w. o6 r7 o- l' @: p
Recursive Search Techniques (回溯搜索技术) e* g+ E7 C& @' U6 j8 A; }Minimum Spanning Tree (最小生成树) 0 n, r! q4 A+ T( K7 S W
Knapsack (背包问题) * ]4 o+ m, x+ C; v' g) e a3 N2 ]Computational Geometry (计算几何学) ; B3 M4 O! |/ X% _) H
Network Flow (网络流) ! k- K, O) v: ]
Eulerian Path (欧拉回路) 3 \2 e, \' I0 V$ N/ JTwo-Dimensional Convex Hull (凸包问题) , G1 S+ O1 q/ D# m9 M: dBigNums (大数问题) 3 d: v: G/ F! s# F- p& N
Heuristic Search (启发式搜索) ; b3 T+ c! Y$ i( F
Approximate Search (近似搜索) 7 \! `5 j+ r( v7 KAd Hoc Problems (杂题)" q. ]! [8 P6 ]9 d$ f
$ X- j+ R- ]7 `$ Q
很少有人能真正掌握这其中绝大部分的方法,而对于一些包含了这些方法组合与循环的具有挑战性的综合问题,多数选手都无能为力,因为竞赛中的很多试题都需要选手当场作出分析,而不是套用固定的解题格式,这是竞赛的困难所在,也是它的魅力所在。0 H G5 ?2 w: S* J/ C0 n- {
0 Q( q. r* p3 _9 ?5 P三、竞赛准备' l; o4 d& b$ t
ACM竞赛不要求使用某一种特定的语言,所以各个队伍可以根据语言的特点和自己的特长选择,如果对语言的原理语法和特点均能做到成竹于胸、滥熟于心,在比赛的过程中就可以大大缩短调试的时间,从而获得优势。: i8 p. R: d. {6 o& \) @
& v. _+ \) r8 ?7 v
然而编程之道就如武学之道,语言只是各门各派的武功招式,算法和数据结构则好比内功心法和武学原理。内力深厚,任何招式到了手上都能够化腐朽为神奇;掌握了武学原理,更能做到无招胜有招。选手在竞赛中最重要的素质,正体现于对算法和数据结构的掌握和理解上,通过对经典问题的分析,掌握各种算法的应用范围和数据结构的作用与具体实现,是每个选手在平时学习中的重点所在。# b- \$ h: X1 P: |( u: Y
9 u- X1 X" a# S四、竞赛策略, g0 _( y1 I/ D* z2 E
临近比赛,在实力上已经难有质的提高,这时我们不妨将注意力转移到竞赛技巧方面,做不成武学道师也学个韦小宝。在ACM竞赛中,一般来说能成功解决半数或以上题目的队伍已经是相当优秀的,解决所有问题近乎天方夜潭,也就是说无论你的实力如何,都还有很大的改进余地,这其中比较重要的就是竞赛的策略。+ u6 `, _* y |+ m
- u6 U3 X# H/ a4 X(1)分工的问题:$ [; Z. [/ e+ u. Q$ b Y4 A
团队的配合十分重要,三个队员之间的合理分工可以大大改进解题的效率,根据队员的不同特点,不同的队伍可以采用不同的分配方式,其间一些细节的处理需要三个人有很好的默契。 ( P* ~) v- x8 ^/ L; Y7 W6 _' N , K; S+ b6 Q, b$ ^& k2 ^3 y(2)算法的选择: r! g) K u" |- c6 F1 j在所有可行的算法当中,我们选择的应该是最可行的方法,而不是最高明的方法,这是竞赛与解决问题的一个重要区别,按照熟悉的程度由高到低选择一个算法,通过计算算法的时间和空间复杂度(在必要的情况下)和特殊的测试数据找出一切使该算法不成立的理由,如果找不到就确定该算法并选用相应的数据结构。在确定思路的时候注意比较常见的思维方式分析,比如逆向的分析,对称的分析等等。# I. f. |7 Q; |2 t3 s3 u2 y
: T# k t2 c9 Q% U, B(3)程序的编写: & l Y8 i6 U& T! h4 ~2 X, F最好首先编写输入和输出的部分,然后逐步细化,一个部分一个部分地填充调试,其间通过适量的注释来刻画程序的逻辑结构和特殊的技巧。在完成全部代码后用一般的测试数据验证代码的正确性,然后处理特殊的情况和边界问题,试图尽可能地找出错误的情况并加以改正。关于程序的优化主要考虑的是最坏情况下所用的时间是否满足要求,优化的程度以题目要求为准,足够即可,尽量避免使用指针和动态分配,在空间允许的情况下一律采用静态分配。' s1 N' N* y" U4 c% p2 i
9 H+ F* \/ j/ n, [(4)调试中的问题: 5 K4 f0 _8 C5 a+ V! Z# @! M% O调试中会遇到的许多问题需要在事前有所准备并定出总体设计,当然具体的情况还要临场分析,考虑的方面包括程序中的BUG,算法的正确性和数据结构的合理性,什么时候该放弃这个问题,什么时候该返回到先前放弃的问题,是否需要做到或已经做到足够的优化等等。所有关于调试的输入输出都不要删除,将它们注释起来即可。% k9 d' u! Q& ~( N0 Z
1 U+ b! }# n1 h1 d" J" N
(5)竞赛中的杂题处理 : j9 H/ ?- m' V' ?6 b. n6 u4 m在竞赛中有时会出现一些新颖的题型,解决它们的算法很难归到经典的算法中去,每个这类的题都有自己鲜明的特点,对于它们根本没有一般的解法。对于这样的挑战,一个新颖的数据结构或一套特殊的循环或判断常常是必须的。解决这种问题的关键在于仔细地阅读题目的叙述,灵感经常来自于将叙述的逻辑条理整理得十分清楚之后,同样,对这类题的优化也是需要的,至少需要避免过多的循环嵌套。 ; j. k/ E% Y! ]. C% \! G$ x* U7 l1 @5 x
五、编程与竞赛 " z) ~0 R! i2 O学习编程并不是为了参加竞赛,竞赛对于多数选手的意义还是在于参与,以及在备战过程中对自己的锻炼和提高。在这一点上,ACM竞赛和其它一系列竞赛是一样的,只是它的影响力和规模大些罢了,所以笔者希望对编程有兴趣的同学都能够关注竞赛,即使不参加,通过了解竞赛中涉及的编程知识达到课内很难达到的高度,这对每个人都是有益无害的。 3 U7 v: s, h# m. y 3 b, e" ?3 s! Y2 H( k- T " {. ?+ ~3 m& J+ Y, V7 V- B" `6 o+ r% L5 ]( P4 |& X7 a2 J! o9 v
一、语言是最重要的基本功4 @. Q( R' U5 K- \
. K9 `$ `7 E, X0 \ `7、高等数学——纯粹运用高等数学来解决的题目我接触的只有一道,但是一些题目的叙述背景往往需要和这部分有一定联系,掌握得牢固一些总归没有坏处。. S5 a5 H0 b5 u1 b
+ O* w2 E: c0 x, E1 e9 G
以上就是竞赛所涉及的数学领域,可以说范围是相当广的。我认识的许多人去搞信息学的竞赛就是为了逼着自己多学一点数学,因为数学是一切一切的基础。 . _4 o: ]2 [4 K7 f! T, s3 P% ^: S4 _8 x s& j
三、数据结构与算法是真正的核心! O' r# ~1 u2 x" l
4 o, r2 {) \& P9 w
虽然数学十分十分重要,但是如果让三个只会数学的人参加比赛,我相信多数情况下会比三个只会数据结构与算法的人得到更为悲惨的结局。" v1 w2 ~/ b+ S# b& E* J* o4 r! M" ]
3 d8 w. v& z( }+ [5 Q9 w/ g4 [/ Y先说说数据结构。掌握队列、堆栈和图的基本表达与操作是必需的,至于树,我个人觉得需要建树的问题有但是并不多。(但是树往往是很重要的分析工具)除此之外,排序和查找并不需要对所有方式都能很熟练的掌握,但你必须保证自己对于各种情况都有一个在时间复杂度上满足最低要求的解决方案。说到时间复杂度,就又该说说哈希表了,竞赛时对时间的限制远远多于对空间的限制,这要求大家尽快掌握“以空间换时间”的原则策略,能用哈希表来存储的数据一定不要到时候再去查找,如果实在不能建哈希表,再看看能否建二叉查找树等等——这都是争取时间的策略,掌握这些技巧需要大家对数据结构尤其是算法复杂度有比较全面的理性和感性认识。. n G) L8 d7 N' o' M3 {0 h
`# i/ l d' Q7 F接着说说算法。算法中最基本和常用的是搜索,主要是回溯和分支限界法的使用。这里要说的是,有些初学者在学习这些搜索基本算法是不太注意剪枝,这是十分不可取的,因为所有搜索的题目给你的测试用例都不会有很大的规模,你往往察觉不出程序运行的时间问题,但是真正的测试数据一定能过滤出那些没有剪枝的算法。实际上参赛选手基本上都会使用常用的搜索算法,题目的区分度往往就是建立在诸如剪枝之类的优化上了。 " b; i4 ]* V) m* t. P$ W. W& W
常用算法中的另一类是以“相似或相同子问题”为核心的,包括递推、递归、贪心法和动态规划。这其中比较难于掌握的就是动态规划,如何抽象出重复的子问题是很多题目的难点所在,笔者建议初学者仔细理解图论中一些以动态规划为基本思想所建立起来的基本算法(比如Floyd-Warshall算法),并且多阅读一些定理的证明,这虽然不能有什么直接的帮助,但是长期坚持就会对思维很有帮助。9 V% m, }' s( l; ^! n% u6 P0 R
9 j! F. n5 x8 Y- r+ L四、团队配合 # {, o- V& Y/ b 0 |) V* A: ^. m) ^+ M通过以上的介绍大家也可以看出,信息学竞赛对于知识面覆盖的非常广,想凭一己之力全部消化这些东西实在是相当困难的,这就要求我们尽可能地发挥团队协作的精神。同组成员之间的熟练配合和默契的形成需要时间,具体的情况因成员的组成不同而不同,这里我就不再多说了。 * r e+ S% V& Q8 Z4 A, ] ! H9 y1 \9 [& ]6 J3 a( d. L" L五、练习、练习、再练习 5 d& z7 ]7 i" F4 h4 p, H ; b: Q5 A8 u; _* M5 ?( V, t. `知识的积累固然重要,但是信息学终究不是看出来的,而是练出来的,这是多少前人最深的一点体会,只有通过具体题目的分析和实践,才能真正掌握数学的使用和算法的应用,并在不断的练习中增加编程经验和技巧,提高对时间复杂度的感性认识,优化时间的分配,加强团队的配合。总之,在这里光有纸上谈兵是绝对不行的,必须要通过实战来锻炼自己。5 C; V0 v, Y) X, h3 k. l
2. ACM-ICPC对选手的要求 ]5 q/ d" w4 Y! x2 k! L: JACM-ICPC涉及知识面广,与大学计算机本科及研究生课程直接关联,在知识的范围、深度和难度上远远超过本科课程n4 s8 o5 u1 @' ?
计算机科学:算法,离散数学,数据结构,组合数学,程序设计语言n1 L7 E$ @: m: B8 `" b
数学:数论﹑组合﹑图论﹑博弈论﹑计算几何n 9 \. o. J& P% V8 k3 c. f英语:采用英文命题,现场比赛的交流完全用英语进行n0 f) M# I% w/ u+ p' q
团队协作:采用3人合作﹑共用一台电脑 d8 l0 n" I& F& eACM竞赛采用5小时全封闭式竞赛,参赛队员与外界完全隔离,完全独立完成,是其实际能力的真实表露,其成绩可信度甚高.ACM-ICPC有严谨而客观的评判规则(大量的严格的数据测试),排除了因评委的主观因素而造成评审不公平的现象,所以,ACM-ICPC对成绩的争议较少,大家比较心服口服. 3 w, x$ ~6 E6 D9 Z/ Q+ _; U
+ U; T: j+ ~5 Y" D0 Z# A' S. y一直以来,人才不一定出自名校,普通环境也能造出辉煌!, Q, J3 j$ _, f% B' D& |
一直相信,荣誉不是学校给的,而是我们自己争取的!! @6 `2 `0 s3 x. k
然而,事实却是—— ( y- j( E/ Y" Z, P ( l, f' e+ O& Y" t$ R1 s诚然,人才不一定出自名校,但处身名校,你会拥有更多的增长见识到的机会! }2 J8 A: _/ P' V d: v6 ] 8 q+ H6 [# \1 D& P诚然,荣誉要靠自己争取,但身处名校,你会更多的成长机遇! % F% g# Y# g8 f2 P, E1 D/ [5 w! Z6 R+ A1 I4 g' ~! j' ?( N
广博的见识,才能让你对世界有更清楚的认识,才能让你更加明白你要做什么!对于各种各样的机会,你才会有一举成名的机遇,才会有产生辉煌荣誉的可能! % o- E5 R$ E: [( s8 v. p: k( G0 m+ l$ O8 w6 [9 K# k7 w3 ^" T
然而,我们不是身处名校,我们能做什么? & d! b+ ]: p! i- b+ f 3 N9 [- A9 ]$ n* \' E不是自怨自艾,而是更加奋进!!!