首先来一张图,很直观(截止到2012年数据)
下面是收集的一些,我改了一下
红色加粗表示特别重要,必须掌握
绿色加粗表示最好掌握,可能性不是很大,但是某些可以提高程序效率
高精度
a.加法
b.减法
c.乘法(应该只会有高精乘单精)
d.高精度除单精 (后面c,d考的可能性较小,应该只考a,b)
排序算法
a.选择排序
b.插入排序
c.hash排序
d.归并排序(单纯的排序可能用不到,有快排就行了,但是归并排序的思想很重要)
e.堆排序
f.快排
字符串匹配算法
a.蛮力法
b.KMP
数论
a.欧几里德算法(用辗转相除法求最大公约数)
b.扩展欧几里德算法 ax+by=c 的正整数
c.素数 O(sqrt(n))
d.筛法求素数
e.快速乘方(位运算+同余+高精)
树论
a.二叉搜索树
b.优先队列(C++中priority_queue,相当于手动维护的小(大)根堆的数据结构优化)
c.线段树 (RMQ问题建议使用st算法)
d.平衡树一种(建议学习SBT)
图论
a.拓扑排序
b.割顶,割边(桥) {O(n)}
c.强连通分支 O(n)
d.有向无回路图的最长路径
e.欧拉回路
f.最小生成树
① Prime O(N2)
② Kruskal O(M2)
g.次小生成树 {简单的删除最大边是不对的}
h.最短路径
① Dijkstra
② Bellman-ford
③ spfa
④ flyod
单源点最短路径算法推荐使用spfa(即使你习惯dijkstra),Dijkstra不能有负边不能有回路,所以用spfa更保险
计算几何
a.判断两条线段是否相交
b.凸包算法 O(n)
其他算法
a.并查集
b.RMQ
......
【COGS】NOIP临考经验
1. 提前15分钟入场,此时静坐调整心态,适当的深呼吸
2. 打开编辑器并调整为自己喜欢的界面
3. 熟悉文件目录,写好准确无误的代码模板
4. 压缩包或许还不能解压,但是文件名已经可以知道了,在选手目录下用代码模板建好所有文件,包 括.c/cpp/pas、.in、.out
5. 开始比赛,不要急于看题目,将试题第一页的时间、内存限制等等一字不落地看完
6. 看题目时不能走神,看完题目后将其归入某几个框架中,包括:模拟/枚举/搜索/贪心/动态规划/图论/分治
7. 根据输入数据的范围大致确定算法复杂度,以下均是可能情况,不绝对:
20:2^20=一百万,O(2^n),搜索
100:100^3=一百万,O(n^3),Flody/APSP/搜索
1000:1000^2=一百万,O(n^2),动态规划/图论
500000:O(nlog(2,n)),二分答案/二分查找/快排/归并
1000000:O(n)或O(1),数学问题/改变思维方向/贪心
8. 写下代码前,必须保证有充足的思考时间,有成熟的想法后再动手
9. 写代码前,尽量用多而强的数据去测试想到的算法,毕竟代码写完后再测试就浪费很多时间了
10. 不能想一点写一点,就算是输入部分也要在整体思路理清后再写
11. 永远别去写从未接触过的算法/数据结构
12. 有多余时间一定要进行对拍,即3个程序:生成数据、朴素算法、准备交的算法
13. 交之前5分钟千万不要再改动代码,主要留意代码中是否还有测试程序时留下的痕迹
14. 走出考场后,除非已经是Day2,永远别对答案
考前准备秘诀
<一>程序习惯注意
一、Linux与Windows的区别
a) 大小写敏感
i. 在Windows下,文件名大小写不敏感,例如A.PAS 与 a.pas 与 A.pas 与 a.PaS没有区别。
ii. Linux视文件名为二进制数据,所以区分大小写。
iii. 考试时一定要看清题目上要求,区别大小写。
b) 关闭文件
i. Windows在程序退出时默认自动关闭已打开的文件,会把缓存中数据写入硬盘。
ii. 在Linux下必须由程序关闭文件,否则没有被写入硬盘。
c) 回车符与换行符
i. 在Windows下,两行文本间有回车符 (ASCII 13) 和 换行符 (ASCII 10)。
ii. 而在Linux下,只有换行符 (ASCII 10)。
d) Read 与 Readln
i. 由于回车与换行在Windows和 Linux下存在有区别,编程时要格外注意。
ii. 尤其读字符串时,尽量采用Readln,而不要 While not eof read或While not eofln read。
e) 多余字符过滤
i. Arbiter评测系统有多个插件,分为整数比较(过滤无效字符)和逐字节比较。
ii. 由于评测插件的原因,注意输出结果时,尽量不要有多余空格或换行。
iii. 对于一个整数,使用write输出。
iv. 对于多个整数,输出最后一个时不要有多余空格或换行。
v. 对于一个字符串,尽量使用write整体输出。
二、保存文件a) 注意文件名,保存要求,目录结构等问题。
b) 某些省份(如 河南)要求同时提交.exe文件,注意不要漏交。
<二>考前十点提醒
一、一定要想好了算法,思路清晰了再编。分析问题时遇到一些即兴问起的情况,马上要深入下去,看已有的算法思路是否有问题。经验证明,这种即兴提起的问题往往是决定算法正误的关键问题。这是一种本能的质疑,本能的差错,一定不要想:我一会再来看这个问题。一定要立即想清楚,看算法怎么样处理才能解决这样一个问题。确认算法没有什么错误了再编。如果思路没清晰,算法不对,编到一半时才发现错了,这种情况没有考虑到,浪费了很多时间,或者编完了都还不知道算法是错的,最后由于样例特殊,过了样例,以为对了,但实际上只得10分,或者根本不得分。
二、对于简单的题,一定要考虑全面,不是编好了程序再来考虑全面,而是想算法的时候就要考虑全面。不要知道个大概就开始写,后来发现一些特殊数据要作特殊处理,又把程序改过去改过来,改得面目全非,最后老是改不对,不但影响心情,而且还是错的。
三、看题要灵活,不要绊死在一道题,不要怕。NOIP的题不想就做出来,怎么可能,肯定是需要想的。但是最好先写好写的题,不一定是前两道题。其实很多时候你是有能力做起的,只是你一看就怕了,也没有去认真想,随便敷衍想了一点特殊情况的算法,认为可以骗到分。但经验证明最后基本是没有分,即使有,最多不过10。时间是3个小时,要积极一点,经验证明,很多题想到一定时候便想出来了。并且很简单。
四、一定要认真读题,读的时候积极思考,看看这某句话到底是个什么意思,要会转换。特别是对于有时间的问题,到底把时间看成一个点,还是一个区间,具体题目具体分析,一定要符合题意。题没读懂就开始做,100%是错的。题错,思路也就错,时间浪费了, 数据还是1个都不过。
五、思考算法的时候,一定要考虑到特殊数据,或一些特殊情况。想好算法,写下各个变量的意义,明确使用的时候都是遵照这些意义的。写下关键的句子,分清各种情况,这个阶段最重要,一定要仔细,不要急着编程。写完了,还要再看各变量是否带对,是否有笔误。等到这些做完了,重复看下整个算法实现过程,等自己解题思路清晰的时候,才开始编程。
六、理清了思路再编程,写好了关键句子再编程,弄清楚了变量再编程,速度会很快,而且正确率也很高。
七、一定要先思考清楚。很多人就是犯不思考就编程这个错误,最后自己就昏了。于是浪费大量时间,而且题也做不出来。一定要避免这种情况。这样就能胜于别人。
八、程序按照思路编完之后,查编译错误。经验证明,刚刚完成的程序不出编译错误的几率基本为0。编译全部修正后,千万不要测样例。经验证明,第一次就把样例过了的几率很低,即使过了,在测自己的特殊数据的时候也会出错。所以,编译完后一定要静态查错。经验表明,静态查错是很有效果的。基本上每次静态查错都可以找到变量代错的错误。特别是快排的I,J是否带错,DEC,INC是否搞错,SWAP是不是加了VAR等等。试想:如果没有静态查错,就去测样例,如果程序有错,样例不过,影响心情;即使样例过了,因为程序有错,特殊数据也不一定能过;即使特殊数据也过了,程序有错,评测的时候绝对会错。发现错了,影响心情了,还是要来静态查,心情不好,肯定效率低。那还不如一开始就静态查,即使发现错误,获得成就感,心情很好。千万不要慌着去测。要保证程序无错,思路清晰,结构清晰了,然后再去测样例,再去测特殊数据。样例过了不要得意,特殊数据过了不要得意,很有可能还有很多特殊情况你没有想到。
九、做好心理准备,也许做了两道自己认为会全对的,还做了一道自己认为能过几组的。可能只得50。这也是有过的事情。除了做好那几个步骤,没有其他的办法。认了吧。搬块石头砸天,也是没有用的。
十、树立正确的成败观。体验第一,拿奖第二。往往能从失败中学到更多的东西,得到更多的感悟。成功固然好,失败也不错。成事在天。做到了自己做到的,就是另一种意义上的成功。
<三>考前时间利用
一、考前几分钟时间,往往能决定成败,所以一定要做好心态调整。不要去想结果,只看过程,努力了就一定不会白费。
二、在别人紧张、坐立不安的时候,你不妨把时间利用起来。依照惯例,考试前几分钟是可以先调试电脑的,所以这时候一定要做些准备:
a) 设置IDE
i. 默认路径
ii. 窗口大小
iii. TAB宽度
iv. 重启IDE
b) 准备文件
i. 创建.in .out
ii. 创建模板
iii. 熟悉计算机,检查有误故障
c) 休息,等待开考
NOIP前必须记住的30句话
1.比赛前一天晚上请准备好你的各种证件,事先查好去往考场的路线2.比赛之前请先调整你的屏幕分辨率到你喜欢的大小
3.比赛之前请把编译器的字体调为你平时惯用的字体,尤其是注意这种字体中的逗号,点,1,l这种易混淆的字是不是区分明显
4.在不影响视野的情况下,请将字号尽可能调大,方便查错
5.请将题目通读完以后,再开始深入思考你认为最容易的一道题
6.即使这道题再容易,也不要着急写代码,请先明确自己每一步要干什么后,再开始写,轻敌会是你最大的错误
7.即使这道题看起来再没法做,也不要提早放弃,这个时候纸和笔会是你最好的朋友,自己尝试几个例子,也许你就会找到答案
8.请一定先明确自己要干什么之后再写程序,不要走一步想一步
9.如果这是一道动态规划题,请先把转移方程写在纸上再编程
10.涉及到边界处理、加一减一之类的问题,请在纸上举个例子,标上下标以后,在编程时参照纸上的下标写
11.如果思考30分钟仍一头雾水,没有可以实现的算法,请你果断屏蔽掉100%的那一栏数据,开始写60%,50%乃至30%的算法——在NOIP里面,30分绝不是小数目
12.几个常用的复杂度参考:100以下——可能是搜索;100~500——N^3,1000~5000——N^2,100000~500000——NlogN,500000以上——N或1
13.如果你发现你旁边的人写得很快,请你放心,他的算法十有八九是错的
14.虽然1s+128MB内存 (这是以前的了,现在应该是 1s + 256MB) 是标准配置,不过也不是每道题都是这样的,还是请认真阅读试卷首页的试题说明
15.计算内存的方法:数组大小*类型长度/1000 / 1000=所占内存MB数,int(Pascal:longint)类型长度是4, long long (Pascal: int64) =8
16.记不住的话,记住int (Pascal: longint) 型数组在128MB内存下最大开到2500 0000是比较保险的(占100MB内存)
17.写完程序之后,请一定不要忙着编译,请一定要将你的代码从头到尾通读一遍,也就是静态查错,这是整个编程过程中最重要的步骤,有的变量重复调用问题调试的话,一个小时也看不出来,静态查错可以一下指出错误
18.静态查错请注意以下方面:
(1)是否写上了using namespace std? (这是C++的,Pascal就不用了)
(2)数组开得是否够大?
(3)变量类型是否正确?
(4)memset时,所填的sizeof(XX)的XX是不是匹配?大小是不是正确? (Pascal 是 fillchar)
(5)外层循环与内层循环的i,j是不是混用了?
(6)循环之前,i,j是否定义了?
(7)输入数据都输入了吗?
(8)这个程序是在执行你想让它执行的步骤吗?
19.通过样例后,请你一定不要放松警惕,因为样例并不能覆盖所有的情况,请自己设计几组数据,争取卡死你的程序
20.如果出现问题,请你调试你的程序,请一定要分模块调试,不要从头跟到尾
21.如果你已经设计不出能卡住你的程序的数据,恭喜你可以做下一题了
22.如果你用的是windows,请你注意把system(“pause”)注释掉 ( 针对C/C++,Pascal 不存在 )
23.为了万无一失,请你用return 0结束你的程序 ( 同样 , 针对 C/C++ ,建议是必须加上 )
24.在内存允许的情况下,能开普通队列就不要用循环队列,能开下普通数组就不要用滚动数组
25.在时间允许的情况下,能暴力就暴力,高精度能不压位就不压位,优化不需要的就不要
26.总之,在不超限制的前提下,能不优化就不优化,以减少代码量和出错概率为第一原则
27.当比赛还剩下5~15分钟的时候,请不要再改动你的程序,即使你怀疑它对你的一个输入给出了错误答案,因为你自己算出的结果也有可能是错的
28.这个时候请你检查是否注释掉了该注释掉的东西,文件名是否写对,文件夹是否建对,请一定反复检查!
29.今年赛制更改,没有人知道究竟会变成什么样,所以,与其瞻前顾后,不如集中精力做出你眼前的题目来的实际
30.请记住,NOIP不怕暴力,怕瞎算,不怕不会,怕不敢,有时间的话一定要写一个暴力程序去对拍,验证算法的正确性