注意模数看好了不要写错(建议拿鼠标复制下来)
看清楚输出的是 YESNO
还是 YesNo
还是 YE5N0
(测大样例的时候应该能发现)
注意有没有把调试信息删除
看清楚 freopen
的文件名,文件后缀名,w
和 r
,stdin
和 stdout
是否对应。你最好不要第一行写完 freopen
之后直接复制到第二行,这容易出问题!每年都有无数的人踩了这个坑!
看清楚无解输出什么,不要想当然以为无解就输出 -1
看清楚题目的名称,比如之前有人csp,题目名称 snake
写成了 snack
,还是建议直接从题目pdf里复制下来
注意如果 #define int long long
,scanf
的时候不应该 %d
而应该 %lld
多测一定要记得清空!!!!!!!!!!!!
多测的时候,如果数据读到一半就可以算出最后答案了(一些特殊情况),那么你仍然要继续读入剩余数据
最好不要用 ios::sync_with_stdio(false)
这种关闭流同步,这会导致包括不能与 scanf/printf/getchar
混用,和文件读写使用会出现问题等各种奇怪的问题。使用快读+cout是一种稳妥的方法。
cout
的时候千万不要写 endl
!!!!!!!!!!,一定要使用 \n
看清楚行和列。在后续写代码的时候行和列也不要搞反!!!!!
cout<<1.00
会输出1而不是1.00
浮点数要用printf输出,如果使用cout输出的话,可能输出的内容变成了科学计数法,导致wa。
不要开 1e6 或者是 2e5 个deque,如果能手写的话尽可能手写,不然会导致 mle 的情况。这种情况在 NOIP2022 和 NOI2022 中都已经坑害了不少选手
不要对大数组进行类似于 int foo[10000000]={1}
的操作,这会导致编译时间非常慢,且编译后文件非常大,在评测时直接 ce。
和上面的类似,结构体赋初始值需要在构造函数里面赋,否则也会导致上述错误https://www.luogu.com.cn/discuss/713864
无向图记得开两倍数组!
看清楚你要开多大的数组!
如果你要打部分分,更要看好你要开多大的数组,不要想当然地直接开与部分分数据范围一样大小的数组,也不要无脑开100%数据范围大小的数组!
不要就开整整好的数组大小,永远都多开几个,比如1e6开1000006的大小,这样会带来很多福利
如果你的函数参数传递了数组,比如 void fun(int arr[])
,此时在fun函数内进行 memset(arr,0,sizeof arr)
是错误的。因为arr实际上传来的是指针,而对一个指针进行sizeof操作不是其原本代表的数组的大小。因此,对于第三个参数,你需要传递确定的大小
如果你代码数组有的从下标0开始有的从1开始,那你脑子必须要时刻清楚应该怎么做
函数内开的变量或者是数组初始值为随机数,记得一定要赋初始值
注意函数内的变量名不要和函数外的变量名相同,不然会导致各种奇怪错误的发生。比如全局有l和r,枚举四层循环时枚举了i,j,k,l
无符号的数据类型和有符号的数据类型混用(运算/比较)的时候容易出现问题,多加小心!
注意合适的数组清空方式!一言不合就memset容易tle
如果你会指针,不要随便炫技,指针会导致运行速度变慢
你最好使用 cout<<sizeof(arr)/1024/1024;
看数组占用大小来防止mle
赋无穷大的时候使用0x3f3f3f3f(4个3f)可以使得两个无穷大相加不会爆int,对于long long需要使用0x3f3f3f3f3f3f3f3f(8个3f)。如果你不需要两个无穷大相加,那么可以直接使用 作为无穷大(大概 )。为了防止出现re,你最好(long long)1e18
double数组memset初始化正无穷第二个参数用127,经测试floyed不会爆负数,且比1e10还要大
string类型的数组有概率会出现奇怪错误
string容易出问题,还是用 char[]
吧。你可以采用形如 cin>>str+1
(其中str为char数组)的方法读入字符串,而且这样读入是从数组下标为1的位置开始读入的。使用 strlen(str+1)
可获得字符串长度
结构体中使用了string,再memset(a,0,sizeof(a))
,在程序运行结束之后会产生奇怪的re。在linux上没有,在windows下会有。建议在结构体中字符串用char[]
数组越界,可能不re,而是wa,并且可能出现灵异错误(比如把另外一个变量的值给修改了),如果你debug的时候发现灵异错误,不要以为是什么bug,可能是你数组越界了
使用科学计数法,即“1e多少”这样的形式时需要注意,这种字面量的数据类型是浮点数,不是整数,即使你表示的数字没有小数点!这可能会导致ce
由于windows的栈空间有限制,评测的时候栈空间和内存限制是相等的,因此你可能在devc++里re了,但实际上是ac的。你需要在编译选项里加上 -Wl,--stack=102400000
开增大栈大小
最好加上 -O2
的编译参数,防止你没开O2是对的,但是最后评测开O2了就re了
使用编译参数 -Wall -Wextra -Wshadow
可以尽可能显示编译的Warning,你的程序不应该有任何Warning,除非你确定出现的Warning会发生什么
你最好不要直接在代码里写 1e9
这种表达式,容易出现CE
检查非void返回类型的函数是不是都有返回值,定义了返回值类型却没有返回一个值会导致RE
stringstream的clear不是清空! 清空要这样 ss.str("");
如果比赛最后评测使用c++17,那么你要倒吸一口凉气了,因为c++17引入了若干保留字,包括但不限于 size
,next
等
如果最后结果是相减再输出,且要求取模,一定要 (a-b+mod)%mod
,否则会输出复数
暴力能优化就多优化优化,多过一个点可能就一等了
使用滚动数组进行优化时,看好了最终答案用哪个数组!
状压dp由于的极限复杂度,在枚举状态的大循环里面要避免大常数操作。比如可以预处理的数据要预处理。以及不 #define int long long
一定要再三确定快读没有打错,不然全爆零!!!!
要注意留出时间认真审题(最后草草审题写暴力大概率爆零)。
如果题目数据比较容易生成,暴力容易写,而且时间充裕,那么最好使用对拍。
对拍可以考虑生成数据范围小且比较特殊的数据,这样比中等规模随机数据相比对拍速度更快,且出现问题调试起来也更加方便
两片雪花之间
,注意顺序,不一定是l小于r
求两点距离的dis函数,需要这样写 (double)(sqrt((double)(dx[a]-dx[b])*(dx[a]-dx[b])+(double)(dy[a]-dy[b])*(dy[a]-dy[b])))
多加几个double,否则会造成精度损失,进而wa
二分时,如果l和r有负数,那么应该用(l+r)>>1而不是(l+r)/2,否则会出现MLE错误
有可能图不连通
题目如果没有特殊说明,重边和自环最好也要考虑考虑
判断元素是否存在于map中,不要使用 []==
,要用find,因为调用[]会在map中生成一个节点 多次判断存在会使长度非常大
搜索时慎用map判重!会带来负优化
set
要用自带的二分查找函数,否则复杂度会和暴力同等(CSPS2021T1)
离散化,最后是 -a-1
。二分查找最后是 -a
进考场之后千万不要碰电脑
考试的时候不要小声嘟囔,即使忍不住嘟囔也不要带脏字,不然被判定为辱骂CCF会被禁赛一年
不要拿记事本看大样例,因为大样例的换行符是linux格式的换行符,在windows的记事本中无法显示。正确的打开方式是把样例文件直接拖入devc++的窗口里查看
测大样例时,devc++会显示运行时间,根据经验,你在考试的电脑上运行6s的程序都可以在正式评测时以1s以内的时间运行完毕,所以不需要担心tle问题
使用fc进行对比时可能出现问题,详见本文“checker”一节
由于比赛时间紧张,如果你的代码不需要重新编译的话,可以按F10直接运行,省掉重新编译的时间。
不要在代码里出现CCF字样,否则禁赛1年
如果需要对暴力算法进行优化,请务必确保你最开始想到的暴力算法是正确的,不然你会浪费大量时间对一个假的做法进行优化
根据经验,时限比较小的题目一般是难度比较低的。数据范围给的比较简单的题目一般是难度比较低的。t1和t2中有一个本场比赛最简单题目,t2和t3有一个本场比赛次简单题目,t4永远是最难的(上述规律仅为一般规律)
注意运算符的优先级。如果你怕出事的话,我们建议你多用几个括号括起来
min(a,b)
写成了(a,b)
for循环的上界不要随时计算,比如 i<=sqrt(q)
,i<=strlen(s)
(ans==10? 'X':ans)
这个代码就会出现莫名其妙的问题 (P1055)快速幂
并查集
while(x!=fa[x])
写成了 if(...)
并查集没有初始化
并查集合并时注意一定是合并两个元素的祖先!!!!!
st表/倍增求lca
st表取lg的时候从2开始循环,倍增求lca取lg的时候从1开始循环
st表 j<=n-(1<<i)+1;
st[r-(1<<k)+1][k]
两处注意+1
倍增求lca x=fa[x][lg[dep[x]-dep[y]]-1];
int k=lg[dep[x]]-1;k>=0;k--
注意两处-1
主席树
fhq-treap
split完忘了 update(now)
注意开数组时除了算上操作次数,还要算上一开始就插入的数
线段树
注意开4倍空间
别忘记pushdown和pushup
别忘了一开始build建树
modify操作到最后别忘返回(写dfs的时候也要注意这一点)
图论
遍历图的时候,把 edge[i]
写成了 edge[x]
无向图,edge数组忘开两倍
tarjan算法时,将点弹出栈后忘记 vis[x]=false
求次短路的时候优先队列中以dis1为关键字排序
求最短路的时候从队列/优先队列中取出元素后忘记pop
kruskal重构树开二倍大小
看清楚题目让点差分还是边差分,写的时候不要把边差分和点差分写混了
春季测试时给出的大样例,如果在windows系统下直接使用fc进行对比,会报有差异,即使你的输出的答案文件是一样的。这可能是大样例的换行符出了点问题。如果你遇到了相同的问题,不要惊慌,你可以手写checker来进行对比
cpp12345678910111213141516#include<bits/stdc++.h>
using namespace std;
signed main(){
ifstream a,b;a.open("tree.out");b.open("tree6.ans");
int x,cnt=0;
while(b>>x){//直到读不到数字了才结束
int y;a>>y;
cnt++;
if(x!=y){
cout<<"WA at "<<cnt<<endl;
return 0;
}
}
cout<<"AC! "<<cnt;
return 0;
}
你需要包含题面第一页所写的所有编译参数,除此之外,还有下面这些
-std=c++14 -O2 -Wall -Wextra -Wshadow -Wl,--stack=102400000