转自:http://hi.baidu.com/ordeder/item/2a342a7fe7cb9e336dc37c89
2009年09月06日 星期日 21:55 初识ACM
最早听说ACM/ICPC这项赛事是在大三上的算法课上张老师提到的,当时我们学校的组织参加这项活动才刚刚起步,我也没太在意,总觉得那是非常遥远的事,事实上当时我也从未相当如今我们能获得现在的成绩。真正踏入ACM/ICPC这个神奇的世界,不得不提到2004那一年我们学校的参赛队伍xmutank,正是听了pipo师兄的精彩演讲以后我才对这项赛事充满兴趣,真正开始充满挑战的ACM之旅。第一真正的训练是从2004的寒假开始,也许不能说是训练而应该称之为“玩”, 事实上我一直喜欢把做题称之为“玩ACM”,我觉得ACM/ICPC是任何一个热爱挑战,热爱计算机的人都会喜欢的游戏。面对一道道难题的挑战,用最优雅、简洁的算法在最短的时间内解决问题。为一道难道辗转反侧彻夜难眠,一朝得解欣喜若狂如痴如醉绝不是玩笑。算法之美,代码之美绝不逊于游戏之美。“玩ACM”和玩游戏一样会上瘾的,我不知道别的ACMer有没有这种感觉,至少当时的我有这种欲罢不能的欣喜。当时我的“玩伴”是ferret_chao(郑陈超,csd 02级,我05年的队友)和arxor(张弛,csd 03级,我06年的队友)。我们的主要的活动区域是pku online judge,也就是大名鼎鼎的poj。那个时候poj的规模还远不如现在,题目总数也就是在1200上下,我还记得当时排名第一的是北大的daofeng,过题数也不过600,我们三个后来都超过这个当年的第一了,不过这是后话了。这个时候大家实力都很弱,难题基本不会做,做的都是那些过题人数最多的题目。我们三个也算的上是不打不相识了,本来那个时候在xmu在poj上混的就不多,活跃的也就只有我们三个,结果就是大家都憋着一股劲,谁也不想被谁超过,一有谁过了一道题,另外两个马上跟进,非得把它也过了不可。而一旦做出一道别人一直搞不定题目,肯定得得意半天。那种竞争的乐趣,多年以后的今天回想起来仍然历历在目。
暑假拼搏
如果说04年寒假的玩耍是一种启蒙,那么05年暑假的训练就可以称得上真正的刻苦训练。可以说我们几个都是自己摸爬滚打走过来,事实上我们很多其他的ACM的强校完全不同,我们从头到尾都没有过正式的训练,完全是依靠到处搜集的资料,论文来学习,这和当时我们学校在ACM方面还没什么经验有关。现在已经好很多,据我所知张德富老师开的算法课已经引入ACM题目作为实验,而且我们这几届ACM队伍也留下了很多以前收集的资料。不管怎么说,当时我们确实是没什么经验,就靠着一本算法导论就开始我们的集训。05年我们学校有两队,一队是我,ferret_chao和jason_chen(陈竞驰,csd 02级),另一队是arxor,xmutank(魏丽君,csd 01级,04年的老队员)和Lucifer(董旭,生物 03级,曾经参加过noi)。这个时候我们开始做一些难题,也不再是孤军奋战,而是充分利用集体的智慧。碰到难题,除了自己冥思苦想,三个队员还会交流解题思路和想法。当时我们队的三个队员住在一起,每天同进同出,从早上11点起床到晚上十一点之间,几乎除了吃饭,都在做题、思考、讨论,那是一种全身心投入的快乐。当然,十一点过后是娱乐时间,没有人可以一整天都紧绷着,劳逸结合才是王道。就是这种投入和交流让我们的知识积累速度和能力提高速度都大大提高,这一段时间是我们实力提升最快的时候,几乎每天都有新的收获,学到新的理论,或者解决新的经典题目。我坚信实战是学习的最好方式,我始终认为自学能力是所有ACMer,乃至所有计算机学者最重要品质。前面提到中国赛区的竞赛要经过网络预赛,而每个学校只能有一支队伍能进入现场赛(参加过世界总决赛的学校可以多进一支队伍,预赛前十名的学校也可以多进一支队伍,我们没想过能进前十所以假定只能有一支),但我们有两支队。所以,要参加现场赛,我们队面临的首先是要击败另一支队伍。所以,这个时候我们除了训练就是关注另一支队伍的情况,每一场热身赛都卯足全力击败他们。说实话,他们的基础比我们要好,一个是04年的老队员,一个noi上来的,都是经验丰富的老手。不过,我们虽然基础稍差,但是胜在斗志十足,要知道我们三个人都是放弃考研机会把所有精力投入这项赛事上,怎么也不愿意付出这么多到最后连预赛都出线不了(当时系里面承诺拿到银牌就能保研,不过后来没有兑现,只提供了保研复试机会),也许正是这种背水一战的压力,才让我们一次一次的超越自我,最终三次击败张弛他们。05年国内有三个赛区,成都,北京,杭州,我们两只队伍在三次预赛都获得出线权,而我们队均以微弱优势稍胜一筹,而且再成都赛区发挥出色获得两个出线权,所以最终我们队去了成都和杭州,他们去了成都和北京。
成都、杭州
成都之行,是我第一次坐飞机,第一次坐火车,第一次出省,第一次参加*的大赛,第一拿到银牌,汇聚了太多太多的第一次。第一次走上赛场的,说不紧张绝对是自欺欺人的,我不知道别人的情况怎么,我和陈超两个几乎一夜未眠,满脑袋填满了紧张和兴奋。说实话,在成都那场比赛,大家状态都不算好,而且川大似乎也没有举办比赛的经验,题目出得难度过高,没有简单题练手,直接就面对一堆难题,很有一种被打击的感觉。当时过的第一题是道无比复杂、恶心的模拟题,之所以选这一题是因为其他的题目都没有思路,只有这种依赖细心和编程技巧的题目我有信心一是。确定题目以后我开始敲代码,陈超和竞驰他们两个考虑其他题目。花了一个多小时,我的代码敲完,居然第一次提交就过了。事实上,这么顺利的过掉这道题目我自己都很惊讶,当时场上还没有人解出这道题目,赛后我们才知道整场比赛结束也只有两支队伍过了那道题目,当时的我绝对算得上是人品大爆发。因为这次爆发,才让后来我对模拟题目有了无比的信心,被队友戏称为“模拟题之王”,碰到这种题目基本都交给我解决。基于我的超常表现,我们又重拾信心,群策群力经过一番苦思冥想又解决了一道题目,最后以第十六名的身份拿到一块银牌。这块银牌是我们学校在ACM上取得的第一块银牌,也是对我们几个月来辛苦训练的一个肯定。两周之后的杭州之行时值教学评估,没有人关注我们,这一次我们是独自踏上征途的。经过了成都之行的洗礼,紧张已经消退,剩下的是激情和信心面对新的挑战。在这里,我们见到了大名鼎鼎的LouTianCheng楼教主。不过教主似乎不太状态,表现居然还不如我们,这也小小满足了一下我们的虚荣心。而这一次,我们三个队员一人做出了一道题,最后以三道题第九名拿到了我们的第二块银牌,结束了05年的ACM之旅。
北京、上海
一年以后,半数老队员退役,三位新队员加入(张俊彬 csd 03,项光特 csd 05,吴笃敏 软件 05)同时由于上一年的我们在奖牌上的突破,ACM/ICPC在我们学校的知名度提高了不少,除了我们以外还有一些爱好者在做题训练,现在poj搜一下xmu已经可以看到很多身影,不象当初我们刚开始的时候那么形单影只。希望随着学校对ACM竞赛越来越重视,会有越来越多的同学参与道这项竞赛当中来,他们都是珍贵的后备力量,有他们才有我们学校ACM竞赛的未来。其实我们参赛获奖除了获得荣誉,获得肯定以外,更高兴的通过我们的努力让学校注意到我们,吸引更多的同学进入这项赛事,喜欢这项游戏。客观的说,我们学校在ACM上的投入相当的少,不提上海交大夸张的近百万的经费,就是与其他的一些学校相比也颇有不如,不管是在赛前培训,训练机房,还是比赛经费方面都还有很大不足。不过,现在已经有很大改善了,这也是我们的实力得到学校肯定的结果之一。去年另一个令人欣喜的是,我们还组建了一支女队,她们是(吕武玲 csd 02,林倩瑜 csd 05,黄文秀 csd 05),虽然实力稍差,但确实是开创了历史。而这一次我的队友是张弛和项光特(csd 05级)。 客观的说,这一支队伍是我们学校有史以来实力最强的一队,擅长编码,实战能力超强的我加上理论扎实,数学功力深厚的张弛,还有一个在noi久经考验的项光特,我们自信已经有挑战国内任何一支强队的能力。在暑假训练的时候,我们就信心十足,可以说今年我们就是冲着金牌去的。而在poj的热身赛中两次夺得第一,更上让我信心暴增。北京之行就是在这样的背景之下开始的。在去之前,对清华充满了憧憬,和大多数人一样我也曾经梦想过成绩清华学子。可事实总是残酷的,我再次体会到厦门大学的美丽名声在外确实不是没有来由的。再加上北京阴沉的天气,清华竞赛的组织不力,心目中清华的形象几乎破灭殆尽。在后面的现场赛中,我们先是由光特过了一道简单题,然后我过了一道搜索,最后他又过了一道博弈。虽然我们只过三道题目,但是由于我们做题的时间都很短,罚时很少,最终只排在过了四道题目的中国科学技术大学之下,获得第二名,拿到我们的第一块金牌,并且获得了参加世界总决赛的资格。能获得这样的成绩有很多的原因,第一是清华举办的比赛,他们自己不能派队伍参赛,导致名震天下的楼教主没有出手,第二是传统强校上海交通大学没有派队参赛,这无形中减少了潜在的对手,当然最重要的是我们已经有了足够挑战金牌的实力。北京之战是我们的成名之战,ACM社区就象是一个江湖,在这里你最大的依仗是你的实力。所谓一朝成名天下知,等我们到上海大学参赛的时候,就不再是默默无闻,一不小心就被当成是厦门大学的牛人,让我们很是虚荣了一把。如果说在北京夺金靠的是项光特的神勇表现,上海的金牌就是靠我的人品大爆发,一开始我就过了一道简单题,然后和张弛讨论以后过了一道树状dp,接着又过了一道搜索。稍后,项光特过了一道数学题,最后经过不停的优化我终于又过了一道搜索。最终我们排在了第七,排在我们前的是两支清华的队伍,两支上交的队伍,两支复旦的队伍,由于上交和复旦已经在其他赛区获得第一不计入排名,而同一个学校只算一个排名,我们最终还是排在了第二。只能拿到第二是有点遗憾,但是已经是超出预料的成绩,夺冠的任务就交给将来的师弟师妹了。
东京
只有走出去才知道世界之大,整天窝在厦门这小小一隅确实有点坐井观天了。说实在的,我对日本这个民族印象很差,大概是在国内负面的报道听多了,总觉得日本人很猥琐。实际情况完全不一样,东京市区我们没时间去,但是从机场到东京湾希尔顿酒店路上的匆匆一瞥,东京给我的感觉是一个很美丽,很整洁的城市。日本人的确是相当的谦逊有礼,在各个商店买东西的时候感觉特别深刻,服务态度出奇的好,联想道国内某些商家的行径,确实令人感慨。不过,这也可能是因为我们住的地方是东京湾度假村,这里就算是在东京也算是高消费地段。这一届的ACM/ICPC World Final 是由IBM日本分部和ACM日本分会联合举办的。赛程设置和竞赛场地都和国内赛场不能同日而语,从赛前的Disney半日游,到IBM提供的技术讲座,从开幕闭幕精彩的晚会,到比赛现场周到、体贴的设置,还有每天晚上的CyberCafe,无不体现了他们对比赛的重视。主办方也一再强调,这不单单是一次竞赛,而且是一场世界性的盛会,目的是为全世界的计算机界未来精英提供一个交流的平台。但是,很遗憾的是我们不得不辜负他们的好意,为什么这么说呢?很简单,英文能力不够,根本没法交流。不出去真的体会不到英语作为一门世界语言究竟有多大的意义,不管是哪个国家,说什么母语,只要会说英语就能够很容易的打成一片,我们这些一出去就成了半个聋哑人的家伙也就只能看着羡慕,暗下决心回去好好学英语。最后谈谈Final的感想,我要说这一次比赛是我们表现最糟糕,暴露出弱点最多的一次。这么说似乎有点王婆卖瓜的嫌疑,但事实就是如此。一开始我们表现还不错,我过了一道简单题,接着光特也过了一道简单题。比赛大约进行了一个小时,这时候光特犯了一个错误,他开始做一道关于空气压强的数学题,这种题目是他的强项,但可惜的是这是整场比赛第二难的题目,到最后也只有两只队过掉(就是第一的华沙和第二的清华),结果他把时间都耗在上面一直最后都没解出来,相当于我们队伍损失了一员大将。接着张弛也犯了错,他挑的是一道图论题目,那也是他的强项,结果那是最难的一道题,而且题目有错误,到最后都没人过。而我选的是一道模拟题,难度适中,本来说这也是我的强项,可是不知道哪个家伙出的题目,题意晦涩的很,导致我连续三次看错题目,过了很久才解决。等第三道题目搞定以后,时间已经过了三个小时。而这个时候,张弛也放弃那道最难的题目了。现在摆在我们面前的有三道题目可以做,一道是搜索,两道平面几何的题目。其实这是一个挽回的机会,比较好的选择是我去攻搜索,光特和张弛一人一道几何题,或者三个人合力攻一道题目,这种策略估计还能做一两题出来。可是,光特陷在那道题目里面抽不出来,我一时头脑发热选了一道几何,张弛选了另一道几何。结果是最后谁也没弄出来,排到了第44名,这暴露了我们平时比赛都是单干,到了关键时候配合不力的弱点。而对我而言,正常情况而言搜索是我的强项,那道题我完全有能力做出来,当时没有去做是完全是因为上一题一直理解错导致我对那种复杂的题目有了畏惧感,结果错失良机,心理素质还不够过关。不管怎么说,能走出国门,能杀进世界总决赛,见识一下完全不一样的世界,看到一只只大牛从眼前飘过我已经很知足了,已经让我收益终身,小小的失利也不算是很大遗憾。
经验
ACM竞赛涉及的方面很广几乎囊括计算机科学的所有方面,主要有下面几个方面:
1、程序设计能力:熟练掌握一门程序设计语言:C/C++, Pascal, Java。大多数oj上都提供以上三种语言的支持,但Final似乎不提供pascal,语言我推荐C/C++,价格便宜量又足。:)
2、数据结构:栈、队列、堆、二叉数、并查集、线段树……事实还有一些我也没掌握的数据结构,例如说后缀树什么的。
3、算法:搜索、动态规划、图论算法、递推、递归、二分、贪心、分治……包括所有经典算法,还有经典算法的结合,例如二分加贪心,搜索加图论什么的。
4、相关知识:图论、数论、组合数学、计算几何、编译原理、操作系统、各种的数学结论……有的时候要用到一些莫名其妙的数学结论,这种东西要看出题者的喜好,要是碰上正好知道的,那就是你的运气了。
训练方法
1、做题才是王道,过题数超过1000你怎么说都是个牛人。我们几个都是做题做出来,当然除了做更重要的是想,不过我认为,读,做,想是三位一题的,所以统称做题。
2、读书,读论文,尤其是图论、数论、组合数学方面,很多东西都不是课堂上能学到的,一定要积极主动的找资料看。
3、读解题报告,有一些难题怪题,没有类似题目的经验,很难想出解法,这种时候读一些解题报告有助于开拓视野,提高解题能力,但绝对不能对太过依赖解题报告。自己实际掌握的东西才是实力。
组队方案
1、比赛是三个人,配合很重要,谁做什么题,其他人干什么最好都有个计划。
2、组队要合理:各项能力最好能互补,例如一个队伍最好有一个数学强人,在有一个代码强人,总之各个队员能力的并集得覆盖竞赛题目范围
比赛经验
1、心理素质要好,真正比赛的时候,气氛非常紧张激烈,心理素质很大程度影响比赛发挥。(Final的时候,我就是差这么一点)
2、竞赛时一定要注意选题,题目太难要懂得放弃,要参考场上其他队伍都做出来的题目,做的人多的一般比较简单,不要把时间浪费在没什么人做的题目上。(血的教训啊,大家一定得吸取)
收获
收获太多了,可以说参加ACM/ICPC是我大学阶段参加的最有性价比的活动了。除了最基本的,脑子里填充了大量经典算法,其他收获还包括:
1、锻炼数学思维,提高解题能力
2、编程能力、心理素质
3、分析能力、动手能力
4、提高知名度
还有最重要的,玩ACM乐在其中,绝不是任何其他枯燥的课程所能媲美的。
后记
ACM的世界,充满了激情和挑战,远不是我糟糕的文笔所能够描述,想要体验它的神奇唯有亲自进入方能了解。