: ]" }' _1 M0 i V2 w在译者序中我也略谈到了自己翻译此书的动机。和很多读者一样,最开始当然是奔着作者的名头去的,三位作者不但是国际知名的选手,而且TopCoder的最高rating加起来都破9k了。顶尖实力的作者往往可以站在更高的高度指点江山,也就更可能写出一本好书。随后就是读到书中的内容了,书中的绝大多数东西,我大概都在过去四五年时间的摸爬滚打中,逐步通过各种书籍、网络、道听途说、解题经验和总结体会掌握了。不过还是有一些耳目一新的内容,其中有一两个问题还是通过邮件得到了原作者的解答,涨了姿势。但仍有一种相见恨晚的感觉,假如自己早两年读到此书,想必能少费不少劲。从我个人的经历和对周围同学的了解来看,这是一本非常值得引进和推荐的书。6 ^7 i% p* x x8 [ o
5 |0 L9 m, W' H5 e ~; M8 A& F$ M: x当然,在此之前国内已经出版有不少算法竞赛相关的书籍了,很多人想必希望知道这本书有什么特别之处。算法竞赛相关的书籍大致有两类,一类是算法和数学类的书籍,比如各种数据结构教材、离散数学教材、《算法导论》、《具体数学》等,一类是专门针对算法竞赛的书籍,其中的代表就是刘汝佳所著的几本书,而《算法艺术与信息学竞赛》(黑书)又是其中的代表。作者之一的iwi在MSRA实习期间也得知了黑书的大名。+ f8 r; F {! p0 c+ T
* l7 r+ }! z3 B1 g% v0 T$ s
首先,个人觉得这些书籍大致可以分为两类:教科书和工具书。诸如《数据结构与算法分析》(DSAA)之类的书可以作为教科书的代表,而诸如《计算机程序设计艺术》(大名鼎鼎的TAOCP)则毫无疑问是工具书的代表。大致地说,前者简单易懂,适于学习,后者高深全面,适于参考。二者并没有明显的分界线,很多时候全凭主观,因人而异。比如说,看懂了,这就是教科书,看懂目录了,这就是工具书。当然,和数学沾边越多的书,总是越难啃的,所以就难度而言,这类书籍和编程语言类书籍自然是没有可比性。' m1 m E: i& H. `/ b/ @4 c) _5 B. p
# ^8 b, V$ F; L" ]许多书都作为程序设计竞赛的学习资料被反复推荐,但事实上,我们大概可以仿照《最常被程序员们谎称读过的计算机书籍》写一篇《最常被ACMer们谎称读过的书籍》的吐槽文。里头有一句话很重要,所以我再抄一遍:“如果你自己没有读过这些计算机书籍,请不要推荐给别人”。当然,像《算法导论》这样的书个人觉得还是值得一读的,多数的章节并不难,可以当作教科书,后面的一些内容可以作为工具书需要时再参考,里面很多东西讲的很细,容易做到真正的理解吸收,比如从自动机引出KMP等等。而TAOCP则无疑是最常躺枪的装逼神器。有一天,我在同学的桌上看到一本TAOCP第一卷,打开一看很黄很暴力,我赶紧就把它盖上了。TAOCP很厉害,看exponentiation by squaring能引用到它,看permanent也能引用到它,连看数え上げお姉さん都能引用到它。读完TAOCP那必须能变得超厉害了,可那得是能读完啊,读不完说啥都白搭。所以推荐学习资料不能光看书好不好,还得看对目标人群合不合适。而一本好的教科书,不应该是尽可能体现作者有多牛,而是要能够尽可能简单地帮助读者变得更牛。如果看完了,懂的还是懂,不懂的还是不懂,那是没有意义的。 a8 `5 F: \5 G! G0 S8 C) q. G
% c# ~) W* L" j6 v5 S
按照这个分类标准,个人觉得《挑战程序设计竞赛》是一本很好的教科书。它非常的适合作为有志参加程序设计竞赛的同学自学,或是正在学习数据结构与算法分析的读者作为练习和拓展的参考书。该书将不同的主题按难度分成了三部分,循序渐进。作为教科书,其一个明显的特点是,几乎没有外链,把每个的主题都讲得很清楚,便于读者理解。多数题目附有核心代码,代码风格也不错,而且讲解的时候会附带一些思路的说明和方法技巧的总结。它在正文中详细完整的介绍了在程序设计竞赛中最重要的知识和思想,全书涵盖了在绝大多数题目中所会用到的知识和思想。而对于拓展内容则以补充说明或是附录的形式给出,并未多做介绍。这样的好处是该书很连贯,结合练习容易完整掌握,并突出了对大多数人而言更为重要,应该多花力气的地方。1 W7 [) o! |6 [- k4 g# H
% G {6 |* [. H2 t3 _
在此举几个例子。书中介绍一般图匹配的时候并没有介绍经典的带花树实现,而是介绍了利用Tutte矩阵求匹配数的随机算法。因为要在书中真正把带花树的实现给读者讲清楚很困难,而对Edmonds算法的介绍资料也很多。在介绍后缀数组的时候,用的也不是线性算法,因为后缀数组最重要的是理解其性质和应用,而求后缀数组往往是模板的工作。在介绍字符串上的动态规划算法的时候,没有介绍KMP算法和Aho-Corasick算法,而是用暴力的方法求出了二者所对应的状态和转移,事实上这反而更有助于真正理解KMP算法和Aho-Corasick算法。% z3 T& R: k0 L7 J