这些天刷基础题犯的诡(sha)异(bi)错误大集合 by pkl
———其中可能会有部分资料引用,引用会表明链接,如果没有标明敬请指出QAQ抱歉QAQ
----------------------------------
首先安利一发帖子:OI中有哪些常数优化的小技巧
ps:注意是基础题。所以嘛错误nc需要原谅。。毕竟我也是蒟蒻QAQAQ大蒟蒻QAQ
· 循环里的临时变量出了循环便无效
· 递归的临时变量不要定成全局变量
· 赋值的对象不要一不小心手抖写反了…比如b = a写成a = b【估计也只有我会犯这种诡异的错误了…
· 注意初始化
· …全局变量不要一不小心在函数里定义一遍在外面定义一遍…这样的话在函数里给全局变量赋值最后被赋的是函数内的临时变量<
· 多次bfs的时候不要忘了清空队列
· scanf的百分号个数和地址符…
· 检查逻辑运算符= =
· string的种种注意事项…
· getchar读入单个字符包括回车和空格 getline读入回车空格 scanf跳过空格和回车tab等不可见字符 cin不读,但是它认识<【我这说的都是些什么玩意儿。。
· 写各种数据结构的时候主函数一定要看好有没有把build之类的函数调用全…
· 位运算和加减运算的优先级…比如right son 2 * i + 1要写i << 1 | 1
· 网络流建边的时候注意结点的序号
· 注意类型的范围和精度…比如int 和long long…unsigned long long …double 和 float…
· 优先级拿不稳还是加个括号吧不会死
· 不要忘了puts("");…
· strcpy和memcpy使用注意事项
· stl queue没有clear函数。只能一个while然后一个一个pop
· priority_queue の bool operator只能是重载 <
· 两个for用getchar读入二维的gragh的时候第一个for记得也加一个getchar来读回车…
· 记得看网页编译信息…
· string可以直接用==… char数组用strcmp…strcmp相同返回值为0。。反之为1。。
· bfs想好边界
· dp注意初始化。
· 数组下标越界处理的问题。。比如。。下图://不过poj超范围出数据也不是一次两次了大家都知道23333开大点就行了
· 栈溢出。。int炸了。。种种。。
· const int N = 1
· 每逢dfs 每次调用时初始化变量
· 宏定义。。比如这样:
//泥要开一个N * 4大小的数组 //本来一个const int可以解决结果傲娇的你用了define //然后一不小心写成了这个德行: #define N 1000 + 10 int a[N * 4]; //.......这就直接可以上天了... //这个不大容易查出来。。。。 //不过有一次幸好我侥幸逃过了..因为我是这么写的 #define N 1000 + 10 int a[N << 2]; //233333位运算优先级啊位运算大法好拯救一切2333 = =所以还是用const int吧。。保平安 2333
Example
· 数组大小不要设2的整次幂。会拖慢速度。原因见下图。
· spfa要先松弛再判入不入队· scanf %c读入空格换行符(?)反正少用QAQ
下面一条【引用来源:vijos啦啦啦】
· memset int如果是 1 或 INTMAX INTMIN 会有问题, 因为memset 是byte 8 位为单位设置的。 每个bit 设置为 全0 这样如果是int 就是 0000 全1 如果是int 数组 取出来就是 ffff的时候 是没有问题的, 其他情况如果设置数字过大会有高位byte 地位byte重叠的问题 , 设置为1 会出现 1111的情况. 通俗的讲,比如你int memset为1就是将1变为00000001,然后从数组头开始,每8位填充一个00000001,直到填充的次数等于第三个参数。最后如果是int,那就按Int的位数取出来,得到16843009。
下面一条【此处引用来源:memset陷阱】
· 静态数组作为参数传入某个函数的时候,就会退化成指针,也就是该数组的首地址,其数组的长度信息就丢掉了,这就是在这个语境下退化的概念。这也是为什么在将数组作为参数传递时,同时要将数组的长度也一并传入的原因。比如这样:
void f(int s[],int len) { memset(s, 0, len); } int main(){ int s[] = {1,2,3,4,5}; f(s,sizeof(s)); for (int i = 0; i < 5; ++i) printf("%d ", s[i]); puts(""); return 0; }
Example
当然除了再传递一个数组长度给函数这种方法来防止数组退化成指针之外,还有1种方法是使用数组的引用,加多一个‘&‘就可以了。
下面两条来源:点我QAQ
·前置 ++。后置 ++ 需要保存临时变量以返回之前的值,在 STL 中非常慢。事实上,int 的后置 ++ 在实测中也比前置 ++ 慢 0.5 倍左右(UOJ 上自定义测试)
· 数据结构用指针代替数组
数组在用方括号时做了一次加法才能取地址!
所以在那些计算量超大的数据结构中,你每次都多做了一次加法!!!在 64 位系统下是 long long 相加,效率可想而知。
因此用指针!
这里有个 trick:
由于 C++ 中 a[b] = *(a+b) = *(b+a) = b[a],
因此你可以用 i[a] 代替 a[i],用 1[b] 代替 b[1],多维数组同样可以,你甚至可以用 5[4[3[2[1[a]]]]] 代替 a[1][2][3][4][5]。
用处,混乱代码 233。
---------------------------
to be continued..