分享

来自Oler的信息学经验分享!

 长沙7喜 2018-04-14


今天我们汇总了一些Oler在学习信息学过程中总结的经验教训,希望大家无论在平时做题还是在比赛中都能注意到,当然不一定能覆盖到所有方面,如有更多意见请留言与大家讨论。

书籍推荐:绿书+蓝书(青少年信息学奥林匹克竞赛培训教材 系列)、算法导论、粉书(全国青少年信息学奥林匹克联赛培训教材)、黑书(算法艺术 建议水平高的人看)、新编实用算法(建议水平高的人看)


题库推荐:Usaco(强烈推荐,很经典的题库,Nocow有翻译)、Tyvj(基础题比较多,题量很大)Vijos(一个非常不错的中文题库)、Ural(水平有所提高了可以去做做,也有很多经典题)还有很多题库大家根据实际需要去自己做题!


需要学的知识:40%来自于书本、40%来自于做题、20%来自于网上其它的资料(至少我是这样)


怎么准备noip?(来自贴吧Canis_Sirius


【初赛】
        首先,楼主觉得,c语言是一定要学的。(其实c++和Pascal也可以啦)老实说初赛时计算机基础知识拿分挺难的。。有的东西不知道就是不知道。。拿分全靠后面的程序啊!!全靠语言基础啊!!初赛的程序题很简单,会读就行啦,自己想的内容其实不是很多的。楼主的建议是:认真过一遍谭浩强的《c语言程序设计》……虽然很多c语言大牛们鄙视这本书,但楼主觉得用来入门是相当好的,讲得很详细,你能想到的问题它都能解释到。建议把另一本对应的也买上,也是红皮,略薄一点,里面有教材上习题的讲解,还有一些别的知识。书里面结构体共用体啥的草草看看就可以了,竞赛基本用不到。数值转换、补码反码啥的要好好看,会考到。另外楼主还想推荐一本《嗨翻c语言》,攻竞赛过二级还是看谭吧,不过要是不打算攻竞赛又想学c,这本书是本不错的入门书。。 楼主是渣渣,就看过这两本 觉得挺好T T 求大神们不嘲笑


        总之,楼主当时是八月开始从头看谭浩强的c语言程序设计(一本红红的书)。楼主是午宿嘛,就把书放在了宿舍作为睡前读物。。夏天中午时间也长,用来看书正好。躺着看,看上半小时,看得迷糊了就书一扔睡觉,有时看高兴了精神好,就看一中午。(不过大部分时间是看睡着了被书砸到脸。。)楼主觉得这样利用时间真的挺不错的!既不觉得烦,也不影响正常的学习生活。这样每天看半小时,看二三十页左右,一个月就能看完了。我建议把另一本对应的也买上,里面有教材上习题的讲解,还有一些别的知识。对了,结构体共用体啥的草草看看就可以了,竞赛基本用不到。数值转换、补码反码啥的要好好看,会考到。


        之后呢就要准备前面的基础知识了。楼主建议大家先看看一些数据结构方面的资料,这些比较费脑子。楼主当时是把二级c的公共基础知识的书找来看了看……主要看里面关于树、排序、栈和队列的知识,还有一些关于递归、分治等算法的介绍。其实这些也挺有意思的,而且重在理解,学学也挺好玩的。复杂度呀啥的也要看,考得相当频繁,图论啥的最好也看看,每次都会考,不过这两个东西楼主至今不明白……

        需要理解的都看完了,之后还要留出一些时间来看要背的东西,比如计算机史、计算机设备、计算机网络……这些可以边刷题边看。刷题是相当有用的啊一定要刷!多刷几套,切记找提高组的题,别刷成普及组了。。


        这些做完,差不多就该考了。要能都做到,初赛应该差不多能过了。
【复赛】
        复赛就要自己写程序了,因此,只看书已经不够了。不过不看书也不行,你还是需要掌握一些特殊算法。比如贪心算法,比如动态规划……每年题有好多道,考点不完全相同。因此楼主觉得,这一阶段,你需要不求广只求精了。如果你仍然对某种问题一窍不通,那么干脆丢掉它,研究另外的问题。你要记住,你并不需要做出所有的题。只要做出一到两道,你就达到了目标。楼主去年就完全抛了图论。


        递归一定要熟练掌握!相当好用!以及动态规划堪称noip必备。。可惜楼主没学会。。虽然有点难,但只要攻下它,你可以在我们这个弱省完爆所有人!


        看算法的同时,楼主建议多找一些题看,自己先想想能不能写出来,再看看别人的写法。上机训练是很重要的,最好每天能早点写完作业上机练上一两个题。(楼主那段时间每天九点多十点左右干掉作业……人的潜力是无穷的)平时没时间的话就周末。一开始可以先写些简单的题,比如求最小公倍数啊啥的。。先找到手感,慢慢再看那种你第一眼觉得能做的竞赛题,边看别人的答案边自己想,最后再试着自己写。


        看竞赛题的过程可能蛮痛苦的。。有可能你觉得你能做,但对着屏幕瞪上一个小时想不出来。。但是坚持就是胜利!解出一道的感觉简直是倍儿棒。


常用OI技巧:

1、学会总结,我基本上每学完一个章节的东西就会拿多一段时间来进行总结。总结的时候,先列出一个目录,把这一节学到的知识点写进去。然后在下面分别拓展出这个知识点的原理、用途、编程流程、关键代码、优化、和其它同类算法的比较、复杂度估计、模块化代码、相应习题等等。这样,可以很容易的把一个一个的知识点串在一起记住它。


2、要拿出一定的时间看书,书是人类进步的阶梯。相信很多OIer都很喜欢做题,忽略了看书这个重要的环节。其实只有阅览群书,才能学到更多的知识。例如,某个算法你会N^3的算法,但是某本书上用N^2,甚至N的复杂度就给解决了。如果不看书,如果考试正好出这个知识点,或许你就只能拿部分分了。


3、合理安排时间(特指放假或集训的时候)。清晨7点到9点这段时间,是人们头脑最清醒的时间,这个时间段内,尽量不要去调程序,可以去做一些其它的事情,比如看书、总结等等。而9点之后这段时间,建议去做题,这个时候一般花一个小时就可以编出在其它时间要花一个半小时才能编出的程序。到了中午,吃完饭一定要睡觉,否则下午会很没精神,效率会很低的。下午呢,一般就比较综合了,比较随意了,可以自己安排。晚上,我一般都是继续调程序,因为想不出晚上干什么会高效一些。


4、学会适当的休息,不要长时间干同一件事情。当你编程序进入了一个死角的时候,或许思维会很混乱,总想找出错误或优化这个算法,但是一片空白,很盲目。这个时候,你真的需要休息。去外面小小的溜达一圈,看一看窗外的风景,这样就可以换一个心情,换一个思维。在你休息完之后,你会发现,刚才你之所以找不出错误,是因为身在此山中。


5、养成编代码的良好习惯,这个各位可以参考其它大牛的程序。我的程序一般都是用过程堆起来的,每个程序必有的Init和Main过程,可能Init里只有个read(n),但是为了保持程序美观,完整个人的习惯,还是单写了一个过程。但是不要大量的调用过程,比如在某个3重循环里调用过程,因为调过程也是需要一定时间的。除了这个,我还在每个过程中间添加了一个分割线,以便阅读。还有,各位还需要注意换行、空格等问题,养成良好的习惯,尽量使其美观,方便阅读(附录里有代码样例)。


6、学会心理暗示。这个也是很重要的,当你做不出某个题的时候,一定不要乱,心理默默的暗示自己,既然自己不会,别人做起来一定也不会舒服。当你做出某个题,一定不要盲目的高兴,要把自己的思维控制住,这样才能用形象的思维去做下一个题,所以我们一定要暗示自己,这个题自己会做,别人做起来也会很容易的,不能骄傲。


7、学会抗干扰,干扰有很多类,大概就是人为、自然因素。人为因素,当别人早早的做完题或者别人在说话、讨论的时候,一定要控制住自己,不要慌乱,否则你可能会编的程序最后得个0分,所以一定要在众多次干扰中,积累抗干扰的经验。自然因素,当太阳直射你的时候、当寒风呼啸你的时候、当键盘生硬难敲的时候、当屏幕反光的时候,你一定要学会去适应,因为很多时候在考场上会出现这样或者那样的问题,给你的只有3个小时,没有多余的时间去考虑这些无关的问题,只能适应。综上所述,抗干扰很重要,即使没有干扰,我们也可以为自己去制造干扰。


8、写程序的流程要合理安排,这个很重要,也是非常重要的。我就把自己是怎样做的写出来吧,可能不是太好,只是一个借鉴。

    1)我会用大概5分钟左右去完整的阅读题目,因为多一点时间阅读题目,总会有意想不到的发现。

    2)用10-15分钟的时间去设计算法,要尽量躲避第一印象思路,因为这个思路往往是错的,设计算法不仅要证明这个算法的正确性,还要从时间、空间等因素来考虑是否,千万不要很草率的结束这个过程,因为当编完程序再来改正错误的算法,往往会浪费更多的时间,例如说高一的我,看见题就想做,大概理出了思路就去编程,但是反过头来发现,其实是错的,结果浪费了时间不说,心情还很不好。

    3)利用5分钟的时间写出程序的框架,第一步该干什么,第二步又该干什么,一步一步的写出来,再对每一步进行一些拓展,写出关键的伪代码等等。这样,才能让自己在编程的时候条理性清晰,才能降低出错的几率。

    4)编程10-20分钟,前面的工作都做好了,这个过程应该是非常容易的,注意不要犯打错变量等低级错误就行了。

    5)查错10-20分钟,往往第一次编出的程序都是错的,具体的查错技巧下面会写出来。这样,一个程序就算写完了,我这个算法流程只是提供一个参考,具体每个流程的时间大家可以看情况去安排,一般简单程序30分钟敲完,中等点的50分钟,难点的1个小时左右。这样才可以更上NOIP3个小时的节奏。


9、静态查错。这个是很重要的,也可以说是非常重要的。何谓静态查错,就是编完代码之后,不去干其它事情,只是安静的从头到尾的把自己的代码阅读一遍,比如说普通的编译错误、变量是不是打错了、数组开的够不够大、程序的逻辑性是不是还存在问题等等。这个时候,一般是很容易发现错误的,并且还会有一种成就感。但是如果你编完之后去测样例,可能样例是过了(因为样例是很弱的数据),但是其实程序仍漏洞百出,或者测样例都错了,这个时候会严重影响你的心情,再去查错的话,事倍功半。


10、出测试数据是个大学问。测试数据一般分为,小数据、大数据、极限数据等等。所以我们一定要从这几个方面,各出几组测试数据。小数据可以手算,很容易出结果,相信是OIer最喜欢的。极限数据也是指那些边缘数据,比如说某个数据导致你数组越界、被0除等等,一般很多题目都存在一两组这样的数据。大数据的话,一般是去检验程序是否超时间和超空间,因为结果是否正确,真的很难手算出来,除非很离谱的错误。


11、检验程序的正确性,这个除了设计算法时的证明外,如果有时间允许,我们还可以写一个效率低但是绝对正确的算法来和原程序进行对比。这样,我们利用上面出测试数据的学问,加上这个手段,一般可以80%的判断出你写的这个程序是否正确,进而不断完善。(还有一个小技巧,就是利用.bat文件,判断两个输出是否等价。具体怎么用,可以看附录)


12、善于交流,这个就不知道怎么说了,就是多和其它人交流。

其它:

       1)培养对OI的兴趣。

        2)胜不骄,败不馁。

        3)不抛弃,才有希望;不放弃,才能成功。

        4)天才是99%的汗水+1%的灵感,对学OI尤其适用。

        5)学完某个算法时,尽量把模块化代码保存下来。

        6)如果NOIP一等奖名额只有1个,那么相信自己就是那一个。

        7)制定好目标,分为远大的目标(上哪个大学),中期的目标(拿一等、冲省队、夺金牌),近期的目标(学会哪个算法、模拟赛要达到多少分)。

        8)赛前一周多复习,多做简单题,不要再去钻高难度的题,这是NOIP不是NOI。        

        9)专心致志,学习时就不上QQ,不上论坛。

        10)细心,细心,再细心。


考试时的事项


        初赛没啥……记得带好表,你的考场很可能没有表。我的建议是先做程序题。楼主第一年就是在前面那些题上耗了太久最后程序题没做完,那个亏啊。。有些一时间想不出来的题就先扔掉最后再试,别慌。大神是有的,去年全区最高分九十多呢。。但是,你要记住,过了六十分你可能就是全区前十,过了四十分你就能进复赛,所以,不用有压力。


        至于复赛,按惯例是考两个上午。一个上午三道题。如果你第一天没有做出来题,别灰心,第二天的题说不定会很简单。所以,一定不要放弃!考的时候,先看哪道题有思路。我建议先在草稿纸上大概写写流程再往机子上敲。记得注意数据范围。对于有大数字的题,我的数据类型全都是long long int……


另外:如果你搞不定所有的数据,你可以先写个能搞定30%数据的简单算法。拿分是最重要的,算法只要好用就行,漂亮与否不重要。


一些注意事项:


1.数组上下标要多开几维以防爆数组。 


2.数据类型要注意,大多时候需要开long long(longint)。 


3.做题不能太大胆,想到什么就认为正解是什么;同样的,也不能太保守,无论想到什么都否定算法的正确性。 


4.打对拍时,特别要注意对拍与程序共用的部分,共用的部分一旦打错,即使程序是错的也检验不出来。 


5.某些数组越界在编译器内运行是不会被显示出运行时错误的。

 
6.审题一定要清楚,最好看多几遍题,不要怕麻烦,特别要注意(mod,数据范围,期望概率除外),样例一定要先弄懂。 


7.先打暴力,不管你是否知道正解,因为暴力有两个作用。一是,如果想错正解或细节打错,至少有保底分。另一个是,大部分时候可作为对拍程序。 


8.每打完一段程序,一定要回过头来看一下刚才打过的部分有没有错误,减少错误的个数,节省调试时间。等到程序打完了,脑子里的印象就只有程序主体了。 


9.注意空间复杂度和时间复杂度,空间的大小尽量不要接近其极限。 


10.每想到一种可能是正解的算法,不要急于下手,先看看样例,自己想一想,确保其算法的正确性,不要等到程序都打完了才发现这是错的,大大浪费了时间。


11.时间分配一定要合理,注意如果一道题花了较多时间,应及时放下,先做暴力,保证最低分。 


12.当你想到一种可能是正解的解法却又无法证明其正确性时,应打分段程序,当然暴力不能打错。 


13.为了保证该切的题可以拿100分,一定要对拍,如果无法对拍,记得多看几遍程序。 


14.考虑题目的特殊情况,不要因为考虑少了而丢了不该丢的分。


15.对于简单的题,一定要考虑全面,不是编好了程序再来考虑全面,而是想算法的时候就要考虑全面。 


16.如果思考分钟仍一头雾水,没有可以实现的算法,请你果断屏蔽掉%的那一栏数据,开始写%,%乃至%的算法。 


17.通过样例后,请你一定不要放松警惕,因为样例并不能覆盖所有的情况,此时千万不要高兴,而是应该出数据争取卡死你的程序。 


18.如果程序出现了问题,调试时请一定要分模块调试,不要从头跟到尾看到底。 


19.当比赛还剩下5~15分钟的时候,请不要随意再改动你的程序,即使你怀疑它对你的一个输入给出了错误答案,因为此时你自己算出的结果也有可能是错的。 


20.当比赛还剩下10分钟的时候,即使没有打完也应该停下来,检查是否注释掉了该注释掉的东西,文件名是否写对,文件夹是否建对,一定要反复检查,保证该拿的分都不会丢。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章