你们的姜碧野学长远在美国伯克利,看到大家写的总结,觉得有很多不足之处,他从一个过来人的经验出发,给大家写了长篇幅的分析,句句有很有借鉴价值,每个同学必须去仔细研究。另外姜碧野将会代表伯克利参加下一年的ACM final
我随便看了下大家的总结...感觉信息量不大,总结的都不是重点.....核心问题在于大家可能没有意识到信息学竞赛跟其他竞赛、高考的本质区别......
所以大家总结的常见句式是:“题目好水的,就是那个xx没想到、xxx没注意、犯了个小错误”....或者就是只写写“xxx题想到了xxx算法,让后上去拍,然后就没有然后了”,“我当时有点急...所以犯了xxx错误”...
我觉得大家还认为想算法本身是竞赛的绝大部分内容,而认为后面的code实现是技术活,允许“偶尔”存在各种各样奇怪的小错误小误差.......这种想法是很错误。因为计算机科学相比于数学最本质的区别就在于:数学只关心函数变换的性质,而computer science要研究变换函数具体怎么实现、怎么一步步计算。什么意思呢?比如说排序,数学家只会在序列上定义一个函数f(x)=y,比如f([2,1,3])=[1,2,3]....然后去研究排序的性质(就像我们一般讲题时,纸上谈兵,仅仅是讲讲各个算法怎么组合在一起而已),而cs则会具体研究这个函数每一步的计算过程是什么,不同的计算过程各有什么特点。这是有本质区别的。。
再回到大家写的总结,很多时候只讲了自己想算法的经过,有了一个模糊的“要用那个xxx算法”的想法,就开始搞实现了,然后也不讲自己实现时都想过些什么问题但实际上,具体实现的时候,哪些边界问题要考虑,哪些假设需要去验证,各种变量在整个计算过程中是怎么协调的,会不会什么时候出现bug,都是要系统地去考虑的~这些思维方式是数学家以及其他学科的人完全不具有的(也是很多程序员不具有的),而熟练掌握这种思维方式,正是高级程序员和入门级程序员的最本质区别。
我当年高一参加GDOI2007,我当时也觉得题目不难啊,各种题都想到了算法,但是:1. 写得很慢,每试都写不完4题,2. 最后的其实大难题只知道算法,但想清楚实现的细节,以及最终实现可能还需要1~1.5h的时间。其实在NOIP, GDOI里面,因为题目不是非常难而且你跟你的竞争者实力不差太远,想在“算法”上取胜不容易。更多的是你比别人写得快写得准... 我后来GDOI2008的时候,就非常有条不紊,每道题都想得非常清楚,正是因为多写一年code,各种实现的经验又涨了很多很多.....
只讨论怎么想题,不讨论怎么想“实现”的是所有人的通病,因为那个不好用语言表达。但大家除了要总结自己为什么没想到某某算法之外,一定要学会去总结,自己为什么没意识到那个bug的可能存在?自己为什么写着写着题发现得架构错了,得推到重来?别人写code时候,都想了什么问题?为什么要想那个边界?为什么那个边界会出问题?.....大家必须熟练掌握验证自己程序准确性的常用方法,学会合理预测各种可能的bug。这些其实上是很难的,在软件工程领域有一个专门的“形式化验证”的方向。所以大家必须引起重视,也可以多快看那些软件工程相关的书籍,对于程序测试、模块化程序的编写、良好程序风格的把握等等积累经验。
最后一句话:不要再觉得自己程序写出些小错误,是些“随机”的小误差....不要总觉得想出了算法就很不错了,就跟那些做对的人一样了。你写不出来、写不对,就是差距......
写对一个code,不难...知道这个code为什么是对的,很难.....