这篇文章会罗列大量常见的OI问题,包括一些OI赛制下的专属问题.(第一次发不一定全,之后会慢慢补充,也欢迎各位提供建议)
常见错误
1.十年OI一场空,不开long long见祖宗
2.如果你不是OI的熟练工,不要边想解法边做题,这样很容易思维混乱,实现垃圾,最后还运行不了
3. #define int long long 这个东西非常玄学,有时候能用有时候就是用不了,而且很容易导致MLE(内存超限),所以千万要避免使用(如果懒得写long long可以用 #define ll long long,这个一般不会出错.
4.遇到样例通过的时候千万不要直接交,如果有大样例要去运行一下,如果没有要自己造几个或者对拍.
5.如果运行代码结果不对一定不要慌张,可以用一些技巧提高你调代码的效率,不过最好还是靠经验.这里最有用的方法肯定就是输出一些关键的数组或变量,比如你调一道DP题,如果结果是错的可以把dp数组输出看一下. (如果是线段树可以专门写一个函数用于检查每个段的信息对不对,其实不难).
6.如果你用万能头然后CE了很有可能是你触发了某个不知名函数或者关键字,这里最常见的就是几何题里用的x1,y1,x2,y2等,这几个是关键字,用了就会CE,并且编译器是不会报错的.
7.如果你在实现复杂的算法,一定要记得检查你是否有调用最基础的构造函数(如biuld),这个看着不常见实则太容易错了.
8.对于一些空间消耗非常高的算法(线段树,trie),一定要记得检查内存,这里随意开long long是很容易出问题的.
9.一定要注意如果你怎么调都调不出来,可能有两种情况: (1)你的代码烂的无可救药,这种情况建议直接重写.(2)有很小的概率是你的编译器出问题了,这种情况很少见但很致命,因此建议如果调了太久可以换一个环境.
10.一定要怎么舒服怎么写,如果你强行用一种你非常抵触的写法是非常危险的,因为下意识会让你写错,因此写代码时一定不可以委屈自己,不然反而会自食恶果.
11.对于搜索或递归题目,这种题是非常容易导致一种错误的,那就是 return 1 ,这个报错意思就是本地编译器没办法关掉后台运行的程序,通常过一会儿这个问题就好了,但如果没有你需要打开任务管理器手动关掉这个exe文件.
12.如果你发现你的光标变成了纯实心并且会诡异的删掉一些东西,你只需要按一下 delete 或者insert就可以了.
13.头文件非常不推荐使用一大堆,因为非常麻烦,最好用的就是万能头(bits/stdc++.h),有了这个基本上不需要别的.
14.三目运算符需要用括号框起来.
15.调试完毕后要把所有多余的输出都删掉/注释掉,不然会成为非常隐蔽的错误.
对于OI赛制(CSP...)
1.如果你使用关掉同步流的两个语句是非常容易出问题的,所以尽量不要用.
2.主函数必须是int main, signed main是不可以的,因此不能用#define int long long, 同时一定要写return 0
3.可以在开始写代码的时候在一个非常醒目的地方写上 加freopen!!!!!!!!!!! 这样你大概率就会记得加,同时不要先写完freopen再注释掉,这样很容易出事.
4.freopen的文件名不要写错,其实这个错误很常见.
5.对于windows环境,如果直接复制大样例是没有换行符的,而且非常容易卡死,所以可以用freopen验证一下.
6.考试一定要预留检查时间,倒不是检查代码,更多是检查freopen和低级错误.多检查一遍就多一份保险.
7.考试太无聊不要干一些无脑的事情,比如问候CCF等等,即使是表达对CCF的爱意也是不被允许的,一定不要干这种事情,否则会面临禁赛.
8.如果你对解法没有太大把握可以用多个命名空间封装多个解法,然后通过输入内容选择不同解法,这样可以有一层保险.
9.一些特定语法在linux环境下是无法运行的,这些必须注意.
10.不要把无限递归或者循环的代码交上去,这样会卡死评测机,容易被禁赛或处分.
特定算法
接下来是一些特定算法的注意事项,如果没有学过可以直接跳过,我们从简单的开始
快速排序
1.快排正常人都会用sort,但是sort有一个很大的问题,就是下标可能会混乱,所以一定要注意那个下表是不是对的.
2.如果你用sort,最常见的案例是结构体排序,对结构体排序我们一定要注意cmp数组的判断条件,如果有疏漏你很难检查但就是会出错.
归并排序
1.归并排序涉及的变量非常多,一定要注意这些变量有没有写错的或者是符号打错的.
2.归并是很难调的,所以如果你只是想排序,建议用上面的,如果你要求逆序对,直接用离散化+树状数组.
STL
1.STL总体来说是很好用的,但缺点是常数比较大,有些人喜欢用map去维护各种东西,但这样容易常数爆炸,例如2025的CSP-JT3,如果使用map维护pre数组就会丢掉20分.(不堪回首)
2.STL的内存很容易出问题,如果只是简单的需要用一个数据结构,直接自己写保险些.
3.priority_queue一定注意它不是一个队列,你要它的队首不用front(),用top().
4.pair<int,int>是一个害人的东西,如果参数特别多建议直接结构体,不要一个pair接着一个pair的嵌套,不仅非常难访问也毫无必要.
5.一些数据结构是不能开太多的.一次我一口气开了三十万个set,然后就爆炸了.
BFS
1.BFS的vis数组是很讲究的,需要仔细思考,不要因为做了太多模板题导致思维固化,其实vis可以维护的远不止坐标.
2.BFS这个算法存在的原因是因为queue里面靠前的永远比靠后的更接近答案,如果不是这样就不可以用BFS了.
DFS
1.DFS多数情况是不如BFS的,尤其是面对网格图时,然有一些数字或字符串层面DFS是比BFS要简单且高效的,要仔细分别.
2.DFS一定要防止重复(栈溢出),同时一定要记得调用!!!!
单源最短路
1.最短路算法有很多,要注意使用哪一种.如果边权都为正,一定用dijiksra,因为SPFA是很容易被卡死的.如果边权为负,那大概率要用SPFA,因为虽然SPFA已经死了,但因为负权图用不了dijikstra你的最优选择还是SPFA,尽管它已经死了.
2.如果一个图论题无比困难,要从数据范围入手,通常这些题都有一个变量值非常小或特定,可以从中找到突破口.
3.最短路很容易写崩,最常见的就是dijikstra的优先队列和SPFA的vis数组,这两个注意一下通常就没问题.
4.很多时候你需要了解这些算法不是因为它好用,而是因为一些题目会专门考察你对算法的理解,因此尽量对算法要理解的深入一些.
全源最短路
1.最常见的floyd很容易被低估,但因为它的扩展性太强题目的思维难度往往十分恐怖.
2.Floyd循环的顺序是有讲究的,不能乱改.
3.Jhonson算法要注意的很多,多数情况下是用不上的.
最小生成树
1.虽然你可能觉得Prim就是路边一条,但你仍然需要掌握它,因为有些题目专门考这个算法.
2.Kruskal的并查集一定要判断两个节点是否有一个共同祖先,如果有就不要计数+合并.
3.排序一定要注意不要排反了.
并查集
1.并查集的路径压缩一定要做,否则复杂度太高了,但有些时候路径压缩是不能用的,比如可撤销并查集等.
2.并查集多用于考思维,写的时候一定不能混乱.
3.一定要判断是否有重复合并.
Tarjan
1.Tarjan需要维护的东西很多,例如时间戳,颜色,low数组等,一定不要思维混乱.
2.一个很大的争议点就是应该是low[x]=low[u] 还是 low[x]=dfn[u],这里建议用前者.
背包DP
1.背包是一个非常简单的DP模型,2025年T4就考了一道背包题,这种DP唯一的痛点就是很难调试.所以一开始就要想好转移,否则会非常痛苦.
2.背包的时间复杂度和空间复杂度都需要注意,可能需要降维优化.
3.背包要注意初始条件和内存问题,不可以太粗心.
最长上升子序列DP(LIS)
1.这种DP的两种实现都需要掌握,因为可能会专门考一种实现.
2.这种DP要注意二分的实现,比如使用lower_bound还是用upper_bound,还是干脆手写
最长公共子序列DP
1.很多时候板子是不对的,要根据特定条件去改进.
2.转移很容易出错,要注意.
树形DP
1.注意会不会重复的更新,这里的更新顺序直接关乎结果是不是对的.
2.因为是在树上,代码实现一些细微的偏差就会酿成大错.
区间DP
1.区间DP的区间维护顺序一定是从小区间到大区间,不能混乱.
2.这个算法复杂度极高,要注意使用场景.
ST表
1.这个算法对空间的要求很高,同时是一个静态算法,我们要避免在动态维护算法中使用它.
2.log不要直接用系统的,那个太慢,最好直接开一个数组维护,这样快.
3.如果维护二维的,不要写成火车头,可以实行模块化管理,把维护和查询部分专开一个函数实现.
线段树
1.建议各位用#define 定义l(u) 和 r(u)两个函数代表左右子树,这样可以有效节省码量.
2.线段树最好要封装,这样方便调用,比如如果有多个线段树就很方便,或者树套树时也要简单很多.
3.pushup 和 pushdown一定要变成函数,这样不仅思路清晰面对高难度的题目时也更方便调试.
4.mid取哪两个变量的中间值需要注意.
5.调试时可以专门建一个函数输出所有的区间信息.
6.线段树要开四倍空间!
7.查询时要分多种情况讨论,比如两个子树都没结果,一个有或者都有,因为一些时候需要返回最大值/最小值.
8.一定要调用biuld函数!!!
9.一定要清楚自己在维护什么,不要想当然.
树状数组
1.这个算法的查询和修改操作很容易搞混,这里查询是减lowbit(x),修改是加lowbit(x)
2.算法要开两倍空间!
3.查询后要记得返回查询的值.
4.其他同线段树.
目前先写到这里,之后再写的详细写,欢迎各位一起交流其他算法!

103

被折叠的 条评论
为什么被折叠?



