大腦當機低階大錯誤合集
- ceil 的精度問題:
int a, b;
ceil(a/b);//錯誤的
ceil(1.0*a/b);//正確的
- memset 的順序:
memset(vis, 0, sizeof(vis));
後兩項打反時編譯器不會報錯。
while(L--)
判否後仍然會執行一次L--
:
-
lower_bound 正確使用:
2 -
鄰接矩陣遍歷圖時,嚴格注意強制型別轉換!
for(int i=0; i < (int) ve[u].size(); i++){
int v=ve[u][i];
if(v == fa) continue;
dfs(v,u);
size[u]+= size[v];
f[u] = max(f[u], size[v]);
}
-
P6492 [COCI2010-2011#6] STEP
線段樹維護區間最大連續字元相異長度,附單點修改。
錯因: 左右子樹下標移位
錯解:
int ls= u<<2;
int rs =u<<2|1;
正解:
int ls= u<<1 ;
int rs= u<<1|1 ;
-
[GLFLS 6φ] 去他的物理實驗
double
下的二分(二分實現某點導數間接實現三分)時,兩個 double check()
直接進行比較即可,不用思考什麼差值 eps
,eps
只是用於兩個 double
判斷是否相等,例如 if( fabs(x-y) <= eps )
。
正解:
if(judge(mid+eps,nowansb) <= judge(mid-eps,nowansb) ) le=mid;
else rt=mid;
錯解:
if(judge(mid+eps,__b) - judge(mid-eps,__b) <= eps ) le=mid;
else rt=mid;
-
P4513 小白逛公園
如果陣列開小了爆棧也可能 RE
正解
const int maxn=5e5+5;
錯解
const int maxn=500000;
-
P1253 扶蘇的問題
線段樹維護區間最大最小值,如果outofrange()
為 true
,應該返回 INF
或 -INF
,而非 0
。
正解:
ll qjcx(int u,int l,int r,int L,int R){
if(inrange(l,r,L,R))
return w[u];
else if(outofrange(l,r,L,R))return -INF;
else {
int mid=(l+r)>>1;
pushdown(u,l,r);
return max( qjcx(u*2,l,mid,L,R) , qjcx(u*2+1,mid+1,r,L,R) );
}
}
錯解:
ll qjcx(int u,int l,int r,int L,int R){
if(inrange(l,r,L,R))
return w[u];
else if(outofrange(l,r,L,R))return 0;
else {
int mid=(l+r)>>1;
pushdown(u,l,r);
return max( qjcx(u*2,l,mid,L,R) , qjcx(u*2+1,mid+1,r,L,R) );
}
}
-
P3870 [TJOI2009] 開關
維護單點異或,區間查詢。注意有 lzy[u]
才進行 maketag(u,len,lzy[u])
,如果 lzy[u]
不存在時進行了異或操作標記下傳,會導致錯誤的單點異或,因為他把 lzy[u] == 0
的異或下傳了。
正解:
void pushdown(int u,int l,int r){
int mid=(l+r)>>1;
if(!lzy[u]) return ;
maketag(u*2,mid-l+1,lzy[u]);
maketag(u*2+1,r-mid,lzy[u]);
lzy[u]=0;
}
錯解:
void pushdown(int u,int l,int r){
int mid=(l+r)>>1;
maketag(u*2,mid-l+1,lzy[u]);
maketag(u*2+1,r-mid,lzy[u]);
lzy[u]=0;
}
oier作死技巧
1.賦值運算子與判等不分
/使用-Wall編譯選項會出現警告
if(n=1)puts("Yes");//此處應為n==1
else puts("No");
2.多重迴圈中i,j,k使用分佈不清
for(int i=1;i<=n;i++)
for(int j=1;j<=n;i++)//顯然應該是j++
//do something
for(int i=1;i<=n;i++)
for(int j=n;j>=1;j++)//顯然應該是j--
//do something
3.運算子優先順序(多用括號)
int a=num<<2+1;//這裡會被解讀為num<<(2+1)
a=(num<<2)+1;
int a,b,c;
cin>>a>>b;
c=a+b%10;//此處會識別成a+(b%10)
4.多組資料要初始化變數,區域性變數要賦初值
特別是ans,sum不賦值等。
//比較好的習慣是將變數定義在迴圈內,從而求解每組資料時都能初始化變數
#include <stdio.h>
int sum;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
//int sum=0;
//像上面這樣定義變數就不會出事了
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int num;
scanf("%d",&num);
sum+=num;
}
printf("%d\n",sum);
}
return 0;
}
5.區域性變數與全域性變數衝突
建議全域性變數多采取非常用的手誤名稱,如i,j,k,x,y,z是重災區。
6.邊界判斷&&特判
for(int i=0;<;)
for(int i=1;<=;)
//注意迴圈邊界範圍,特別是陣列是從0還是1開始記錄的
### 9.是否使用了正確的檔案io
```cpp
freopen("t1.in","r",stdin);
freopen("t1.out","w",stdout);
10.是否有正確的標頭檔案和return
非void函式一定要有return,主函式要有return 0;
11.資料大小判斷 是否可能爆int。以及int資料範圍
int:256mb=6.7kwint;
int: 2e9;
12.不要使用x1,x2會卡變數名
13.檢查檔名字!!
turn不等於trun
14.-o2看一下有什麼不同的變化
15.注意使用的輸入輸出格式中會不會有空白
getchar會讀入空行和空格
scanf:%c會讀入空白,“ %c”是可行的
%s,&s[i]+1;//等同於cin>>s[i]+1;
16.while(scanf("[t++]")!=EOF) 天坑!t會多一個
17."no"是字母O不是零0
18.函式命名和呼叫,封裝名稱一致,資料型別一致
19.科學計數法1e9是一個浮點數
20.讀題要仔細
子串是連續的;
子序列是不連續的,但是有先後之分;
子集既不連續,也無先後之分
21.sort是左閉右開區間
sort(a,a+n);//sort a[0]->a[n-1]
sort(a+1,a+1+n);//sort a[1]->a[n];