0xFF
探索一门学问有三个层次:求其解,知其原因,究其思维之本。通俗地讲,就是“怎么做” “为什么是对的” “怎样才能想到怎么去做”。在计算机科学中,前两者分别对应算法的步骤和证明。而长久以来,后者时常与“天赋”一词相关联。在全面讲解算法与数据结构知识点的同时,致力于模型构建与思路分析,帮助我们厘清思维过程的线索和脉络,建立一棵“技能树”,从容地面对算法竞赛的各项挑战,为未来更高层次的程序设计与研究奠定坚实的基础。
当年准备参加信息学竞赛时,所在地区的教学资源相对不足,在大约一年半的时间里,依靠3000道以上的巨大刷题量,才从一名连深搜都写不对的初学者,成长为NOI金牌得主,并入选国家集训队。以来的每个寒、暑假,都参与了相关竞赛的授课、命题等工作。为了把知识清晰、透彻地讲解给学生,不得不转变角色, 从“会做题”的选手,变成一位“知其所以然”的教师。发现在高中阶段的竞赛学习中,因自己死记硬背、不求甚解,导致对许多知识的理解都存在偏差。每次重新审视一个解法、更新一次课件,都对“分析证明”的重要性和“怎样想到一种解法”的思路历程有了更加深刻的认识。
在思维的迷宫里,有的人凭天生的灵感直奔终点;有的人以持久的勤勉,铸造出适合自己的罗盘;有的人迷失了方向,宣告失败。作为算法竞赛的过来人,很欣喜地看到大多数选手无论结果如何,都保持着对程序设计的热情和喜爱,在日后的学习、工作中继续选择了信息科学方向。诚然,悟“道”还需个人,但准备算法竞赛的时间毕竟非常有限。想在彻底从算法竞赛界退役之前,有必要尽一点儿微薄之力,把数年来的所寻所得汇集成卷,只求能从中受益些许。深知作为一名指导者,想要替代时间与见识的积淀,给学习者传播“怎样才能想到这么去做”,是一件难上加难的事情。因此,希望始终保持独立的思考习惯和坚定的批判精神,对于每种模型,不仅能用数学语言推导其正确性,更能自然而然地“说服”自己,使整个程序设计过程完全融于自己的思维体系之中。
认真阅读每一个知识点,动手完成每一道例题和习题,并加以归纳、理解,从一名算法竞赛的入门级选手,达到NOIP一等奖获得者的中、高级水平,并具有相当的自我学习与思考能力。在此基础上,只需涉猎一些新的领域,扩大之势范围,辅以实战训练,不难继续提升到NOI省队平均水平,或具有组队夺得ACM-ICPC区域赛金牌的能力。
应该先对算法竞赛的形式有所了解,掌握至少一门编程语言,能够运用朴素算法求解最基本的问题。大致浏览过一本入门类教材,有100道题左右的练习经验,或者三个月到半年的课余学习经历。对照以下清单进行自我检验:
1)熟悉C++语言的基本语法结构,能够使用C++语言编写程序。
2)会使用朴素算法,如枚举、模拟等方法。
3)理解“递推”的概念,能循环计算简单的递推式。
4)掌握几种常见的排序算法,如选择排序、冒泡排序、快速排序等。
5)熟练使用数组,知道链表、栈、队列的基本结构与用法。
6)能够借助一些C/C++内置函数,进行简单的字符串处理。
7)了解树、图结构,以及其中的常见术语与专有名词。
8)具有不低于高中一年级水平的基本数学素养。
可以在遇到不熟悉的内容时,随时使用Google、Bing(国际版)等搜索引擎查阅资料,辅助学习。
“基本算法” “基本数据结构” “搜索” “数学知识” “数据结构进阶” “动态规划” “图论” “综合技巧与实践”
鼓励先花费适当的时间独立思考,再查看例题的详细解答。算法竞赛最终要落实在程序设计上,请务必动手完成每一道例题的代码实现,方能达到期望的训练效果。
每章的最后一节都包含一份详细的知识点清单,供在复习时对照、检验。这些清单基本涵盖了信息学竞赛省级联赛的知识范围,尤其在动态规划、图论方面具有了相当的深度。在确保掌握了清单中列举的所有内容后,应该自主完成章末的练习题。如果遇到瓶颈,可以谨慎利用搜索引擎查阅题解。
认真阅读完之后,若仍想进一步提高,可以重点关注高级数据结构、网络流、计算几何,并进一步提升数学水平。
关于英文,许多题目的原始题目描述为英文。随着在计算机科学与技术领域学习的不断深入,查阅文献、进行学术交流时,遇到英文的概率将会越来越大。希望借此机会,提前感受英文环境,掌握一些算法与数据结构方面的英文术语,切勿对英文题目抱有逃避心态。
在阅读过程中,希望时刻把自己视作一位科学研究者,切忌自欺欺人、口头浮夸、懒于思考、直接复制;也希望不仅关注结论、模型、算法本身,更要关注它们的分析证明与内在逻辑,建立自然、完整且不容置疑的思维体系。
——by lydrainbowcat