臨時隨筆:大腦當機低階大錯誤合集

ChillLee發表於2024-10-25

大腦當機低階大錯誤合集

  • 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() 直接進行比較即可,不用思考什麼差值 epseps 只是用於兩個 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];

相關文章