代碼易錯(cuò)點(diǎn)
寫題原則:
有錯(cuò)誤先分析錯(cuò)因,再針對調(diào)試。
不要無腦寫,一邊寫就要一邊注意細(xì)節(jié),比如到底是哪個(gè)數(shù)組,有沒有換數(shù)組,是 \(n\) 還是 \(m\)。或者一些邏輯上的錯(cuò)誤。
代碼能力與速度!!寫代碼一定要注意細(xì)節(jié)有沒有寫錯(cuò),尤其是變量不要弄錯(cuò)。
-
靜態(tài)查錯(cuò)一定要認(rèn)真思考正反細(xì)節(jié)比如 \(<\) 還是 \(>\),注意輸出中間變量,根據(jù)輸出錯(cuò)誤答案猜錯(cuò)因。檢查數(shù)組 maxs maxn 是否寫反。不要覺得看著順眼/對稱就覺得自己是對的,比如線段樹合并的是 ls(u) ls(v) 而不是 ls(u) rs(v)。檢查的時(shí)候可能看著 ls rs 對稱就跳過去了。
-
看完題解后不要看題解代碼,按照自己理解寫,如果要看題解代碼的話一定要仔細(xì)看別漏,而且要辨別他的和我的碼風(fēng)的區(qū)別防止細(xì)節(jié)錯(cuò)了。
-
對拍>靜態(tài)查錯(cuò),如果小樣例出錯(cuò),先輸出中間過程。
-
寫代碼一定要專注,思考每一步的正確性,注意細(xì)節(jié),不要犯低級錯(cuò)誤。不可著急去寫,要想清楚細(xì)節(jié)。寫的哪怕慢一點(diǎn)也要把結(jié)構(gòu)格式等等寫好,方便調(diào)試。
-
思考題目注意尋找關(guān)鍵切入點(diǎn),或者思考題面涉及知識點(diǎn)的相關(guān)性質(zhì),往可行方案上靠近,切勿盲目思考。
-
注意數(shù)據(jù)范圍,如開不開 long long 或 maxn 大小。
-
檢查的時(shí)候一定要造特判的樣例測試一下,比如別忘記在特判輸出里面換行。
-
注意用眼,不思考時(shí)合上電腦,眺望遠(yuǎn)方。
-
調(diào)試一定要小心,不要不小心改掉了之前的代碼
-
一定要把式子完整列出來,不能空想。
-
不要因?yàn)辄c(diǎn)小就開小數(shù)組,可能會(huì)有點(diǎn)大的特殊性質(zhì)。
-
審題,第 K 大 OR 第 K 小。
-
統(tǒng)一形式,多合并相同操作,避免混亂。
-
一定要認(rèn)真思考對后面有沒有影響,或者模擬出過程,不可大概想想。
-
一定要注意看輸入格式,或者特殊性質(zhì)。如 CF314E 題目中給大小寫,實(shí)則輸入只是小寫。
-
如果看不懂題解操作,可以自己按題解思路想一下代碼,看看實(shí)現(xiàn)那個(gè)缺什么,缺少的部分就是題解里看不懂的地方。
-
如果看題解一定要認(rèn)真仔細(xì)看,不要漏關(guān)鍵信息。
-
并查集遞歸可能炸,可以考慮循環(huán)寫。
-
一定不能忘記判斷邊界會(huì)不會(huì)超,可以自己測試極端樣例。如 P7960 [NOIP2021] 報(bào)數(shù)
-
\(\operatorname{set}\) 里面一定要用 s.lower_bound 而非 lower_bound,否則復(fù)雜度可能會(huì)退化成 \(O(n)\)。
-
P3177 [HAOI2015] 樹上染色 注意是加的時(shí)候是雙向貢獻(xiàn)加,減的時(shí)候就別忘記除以2,才能保證不被多加。計(jì)數(shù)的時(shí)候可以構(gòu)造很小的樣例自己多試一試。
-
虛擬機(jī)上寫代碼一定要小心,很多錯(cuò)誤不報(bào)錯(cuò)。比如結(jié)構(gòu)體不命名。函數(shù)無返回值。
-
注意題目運(yùn)行時(shí)間,不是 \(1s\)。
-
打擂臺法判斷最值,記得賦初始值,防止最后沒打擂臺就結(jié)束了。如:P2196
-
define 不保證內(nèi)部運(yùn)算先算 AT_arc100_b [ABC102D] Equal Cut
-
位運(yùn)算優(yōu)先級比等號低!
-
注意 \(calc(u,v)\) 不可用 \(sz\) 替代,因?yàn)闊o法確保先傳 \(sz\) 還是先調(diào)用 \(find\) 函數(shù)。函數(shù)傳參一定要小心,注意幾個(gè)參數(shù)之間是否互相關(guān)聯(lián)。
solve(find(v,u),calc(v,u)); -
注意按照我的線段樹寫法下傳區(qū)間的時(shí)候依然是 \((l,r)\)。
-
多測不要亂 \(memset\)
for(int i=1;i<=n;i++) c[a[i]]=0; -
維護(hù)最大和次大值的時(shí)候,如果當(dāng)前值等于最大值也要更新,因?yàn)檫@樣會(huì)引起次大值的變大。
-
lld
-
莫隊(duì)先減后加
-
如果一個(gè)地方代碼修改,注意與之關(guān)聯(lián)的位置代碼也要改。
-
注意弄清樹狀數(shù)組維護(hù)的是什么,如果是值域的話,那么更新的上限一直要更新到最大值而非最大下標(biāo)。
-
如果出現(xiàn)負(fù)數(shù)需要平移的情況,別忘記數(shù)組開兩倍
-
多測判斷對錯(cuò),需要等數(shù)據(jù)輸入完再輸出 No 并推出,否則會(huì)影響下一組
-
P1025 [NOIP2001 提高組] 數(shù)的劃分 注意記憶化搜索刻畫狀態(tài)的完全性。本題還需要加上前驅(qū)的狀態(tài)。
-
不能用 1 直接左移 \(60\) 位,應(yīng)該用 1ll。
-
注意各個(gè)變量名,不要搞錯(cuò)了
-
int大數(shù)相乘注意開long long
-
移動(dòng)溢出后,按位 \(1\) 結(jié)果是 \(1\)。小心!
-
交換 map 是 \(O(1)\) 的。
-
寫完一段代碼,想給 cpp 文件改名的時(shí)候注意先保存當(dāng)前代碼,否則改名后就自動(dòng)不保存。
-
注意如果映射了值,在其他地方別忘了繼續(xù)映射
-
快讀變量名 x f 不要沖突,記得賦值 x=0 f=1
-
貪心匹配的題目開集合注意要開 muliset。小心不要全部刪除了,要?jiǎng)h迭代器。
-
不能一邊用迭代器訪問一邊刪除集合內(nèi)元素會(huì)造成混亂。
-
取集合末尾元素,--s.end() 而不是 s.end()--
-
f[i]=max(f[i],f[g[j]]+(a[i]&a[g[j]]));位運(yùn)算要打括號!!! -
注意輸入的數(shù)中有無 long long s/p lld 開long long
-
if 條件判斷 見寒假模擬賽4總結(jié)
-
隨機(jī)樹的樹高為 \(\log n\),所以對于隨機(jī)樹暴力從一點(diǎn)到另一點(diǎn)復(fù)雜夫?yàn)?\(O(\log n)\)。
-
如果卡常,多組數(shù)據(jù)輸入的 \(n\) 和 \(m\) 記得也不能用普通 cin,因?yàn)榭赡?T 很大。
-
如果要一邊 dfs 一邊判斷祖先的話需要判斷 dfn 大小而非是否有過,因?yàn)榭赡軙?huì)出現(xiàn)兒子節(jié)點(diǎn)遍歷過某個(gè)點(diǎn)后,\(u\) 又枚舉到了這個(gè)點(diǎn)
-
如果線段樹右節(jié)點(diǎn)的信息依賴于左節(jié)點(diǎn)目前的信息,那么就需要先下傳右節(jié)點(diǎn),防止左節(jié)點(diǎn)信息更新后改變。
-
一定要小心檢查各個(gè)特判的地方。尤其是考試結(jié)束前,統(tǒng)一檢查一遍,測一下樣例。
-
K-=sz[ch[u][bit]],u=ch[u][bit^1];一定要注意先后順序,\(u\) 變了之后減的值就變了。 -
P10217 [省選聯(lián)考 2024] 季風(fēng) 一定不要想復(fù)雜了,有相同形式的操作合并即可,而且本題絕對值不需要討論可以直接去,有的時(shí)候需要觀察性質(zhì)。
-
無論是文化課還是 oi ,都要注意如果發(fā)現(xiàn)一個(gè)地方計(jì)算或者代碼有問題需要更改的時(shí)候,注意與之牽連的部分也要更改。
-
擴(kuò)展域并查集記得初始化不止 \(n\),應(yīng)該是 \(k\times n\)
-
小心給出的是森林或者不連通圖,或者自己圖論建模,建出來的不連通
-
決策單調(diào)性的題目,如果有 double,但是答案要求取整,決策中的 \(f_i\) 不能取整,否則會(huì)破壞單調(diào)性質(zhì)。
-
做除法的時(shí)候注意取整,是向上還是向下。如果是向上可以 \(\frac{a-1}{b}+1\)
-
寫完程序尤其是出現(xiàn)問題時(shí)一定要自己完整小心檢查一下小地方,一定要細(xì)致檢查不可一帶而過
-
ll 的時(shí)候 inf 0x3f 注意也要開 ll
-
如果循環(huán)最后還有一個(gè)對于所有情況的處理,不可隨便 continue 這樣就處理不了最下面的那個(gè)更新了。
-
題目不一定升序給出 \(a_i\)
-
掃描線可能無法掃到全局,需要特判
-
for(int j=i;j>=1;j--) b[j]-=b[1];必須倒著減,否則 \(b_1\) 會(huì)改變 -
如果到終點(diǎn)必須停止的話,在可達(dá)性統(tǒng)計(jì)中不能將終點(diǎn)壓入隊(duì)列,最短路中從隊(duì)列中取出終點(diǎn)也不能擴(kuò)展。
-
如果題目中有到達(dá)某個(gè)點(diǎn)可以使用某條件但是限制使用次數(shù)的話,能使用的時(shí)候注意不一定使用。
-
一個(gè)信息如果要被重復(fù)用到的時(shí)候,注意不要著急修改。
-
CF1214H Tiles Placement 注意判斷是否存在三鏈共點(diǎn)且兩兩之和 \(\ge k\) 的時(shí)候,不能只看鏈長是否大于,還需要看看是否有鏈防止出現(xiàn) \(0+k \ge k\) 的情況。并且注意由于此時(shí)鏈返回的長度包含根節(jié)點(diǎn),所以注意需要判斷的是 \(\neq 1\) 而不是 \(0\)。
-
注意有的時(shí)候?yàn)榱朔奖闾幚恚械囊蠡蛘咧挡灰欢ㄒ牖喪剑赡茉礁奖恪?/p>
-
計(jì)數(shù)問題的邊界情況不止是應(yīng)該考慮數(shù)組下標(biāo) \(<0\) 的事情,還應(yīng)該從實(shí)際意義角度出發(fā),也就是說有的時(shí)候不是因?yàn)闋顟B(tài)本身不合法,而是從狀態(tài) \(A\) 到 狀態(tài) \(B\) 這個(gè)過程不合法。比如 ABC134F Permutation Oddness 當(dāng) \(j\) 為 \(0\) 的時(shí)候,無法向前匹配。還有增加匹配。還有就是如果使用了前面的狀態(tài)需要對其限制,比如本來 \((i,j)\) 只需要滿足 \(i \le j\),但是要是轉(zhuǎn)移途中用到 \((i-1,j+1)\) 就需要 \(i-1 \le j+1\)
-
注意優(yōu)化可行性,P8376 [APIO2022] 排列 中雖然我將貢獻(xiàn)式子從 \(2^j(2-1)\) 優(yōu)化到了 \(2^j(2^i-1)\),但是實(shí)際上之前對于 \(k\) 卡得很緊,所以 \(i\) 只能取 \(1\),故優(yōu)化無效。
-
每用到一個(gè)新變量就要把初始化或者清零之類的先寫好,防止后面忘記。
-
注意調(diào)用的函數(shù)的時(shí)候傳入了一個(gè) K,后續(xù)用到函數(shù)參數(shù)的時(shí)候別用 K,而是用對應(yīng)的參數(shù)名。
-
動(dòng)態(tài)開點(diǎn)一定要考慮空空節(jié)點(diǎn),還可能有一個(gè)點(diǎn)開了左邊但是沒開右邊。
-
KDT 節(jié)點(diǎn)對應(yīng)數(shù)組需要用 \(id(u)\)
-
求凸包,輸入 \(n\) 未必是點(diǎn)集大小,要在去重之后重新統(tǒng)計(jì)
-
計(jì)算幾何一定不要用 = 或者 map 判斷相等
-
取模情況一下除法一定要記得逆元
-
取模樹狀數(shù)組如果有加上負(fù)數(shù)操作,一定不要忘記 \(+mod\)
-
不要什么大小都無腦 \(n\)。
-
點(diǎn)分治不要忘記統(tǒng)計(jì)重心點(diǎn)。
-
cdq分治優(yōu)化 dp 注意轉(zhuǎn)移下標(biāo)要用
a[i].id。 -
cout<<(ans^1)<<endl;如果不打括號會(huì)報(bào)錯(cuò),^ 和 << 引起歧義。 -
函數(shù)調(diào)用別忘記寫函數(shù)名,編譯器不報(bào)錯(cuò)。
-
平面只要判斷兩個(gè)相對方向,左上和右下的時(shí)候不需要二維數(shù)點(diǎn),CF1379F1 Chess Strikes Back (easy version)。只需要記錄單維度的最大最小值即可。
-
不要重復(fù)用定義變量。
-
memcpy 注意必須類型相同。
-
當(dāng)值域出現(xiàn)負(fù)數(shù),最小值不要設(shè) \(0\)。
-
造成連續(xù)多個(gè)并列 if 的時(shí)候,如果前一個(gè) if 里面的執(zhí)行語句會(huì)造成后面判斷條件里的變量改變,那么要用 else if
-
如果下標(biāo)域里面有 \(0\),那么樹狀數(shù)組無法正常運(yùn)行,可以考慮整體下標(biāo)加一,注意初始化的時(shí)候要初始到 \(n+1\)
-
多測,后綴和數(shù)組一定要記得對 \(n+1\) 清 \(0\),否則 \(suf_{n+1}\) 可能不為 \(0\)。
-
讀題一定要仔細(xì),有些全局約束或者保證可能放在最下面的測試點(diǎn)數(shù)據(jù)欄下面。
-
改了程序,再運(yùn)行,一定要先編譯。
-
\(n,m\) 不要打反。
-
碼量題注意速度。
-
要小心如果這么枚舉子集不會(huì)枚舉到空集
for(int i=s;i;i=(i-1)&s) -
如果要借鑒題解寫法,一定先要記錄下有哪里常用習(xí)慣自己和題解不一樣,防止后面寫錯(cuò)。
-
\(\operatorname{double}\) 類的最值不要用 0x3f 之類的。
-
整數(shù)除法別忘記開 \(\operatorname{double}\)
-
如果統(tǒng)計(jì)答案在循環(huán)內(nèi)部,注意可能有邊界條件使得不進(jìn)入循環(huán),要在初始化的時(shí)候就統(tǒng)計(jì)答案。
-
注意函數(shù)傳參順序是否正確,還有結(jié)構(gòu)體傳入變量順序是否正確。一定要在每次傳入的時(shí)候去原位置看一下是否對應(yīng)。
-
右移多位是 UB 行為。
-
不要重復(fù)定義變量。
-
字符串題記得多測一定要清空 \(s_0~s_{n+1}\)。
-
const double pi=acos(-1.0);類型不要寫錯(cuò) -
線段樹修改和詢問的時(shí)候一定要小心 \(ql>qr\) 的情況,因?yàn)樵谟械臅r(shí)候某個(gè)東西無意義,我們按照常理賦值后傳入會(huì)導(dǎo)致 \(ql>qr\)。
-
ql=queryg(0,L,R); qr=queryf(0,L,R);一定要先開其他變量記錄,不能用 L,R,否則后續(xù) L 改變導(dǎo)致第二個(gè)詢問出錯(cuò)。 -
權(quán)值線段樹一定要考慮有無 \(0\) 出現(xiàn)。異或可能出現(xiàn) \(0\)。
-
如果二分值域里面有 \(0\),小心 check 函數(shù)里面的除法。
-
(V<<2)+10,一定要打括號。
-
if(n%2==1&&(k<n+m-2||k>=n*m)){ cout<<"NIE"<<endl; return 0; } if(n%2==0&&(k<n+m-1||k>=n*m)){ cout<<"NIE"<<endl; return 0; }注意這個(gè)條件判斷的寫法,不能寫 else 然后不判斷 \(n \bmod 2=0\),因?yàn)榭赡懿粷M足的是第二個(gè)條件。類似 if 要注意。
-
貪心/最優(yōu)化問題對于結(jié)構(gòu)體排序一定要想如何第一關(guān)鍵字相同,怎么排其他關(guān)鍵字。
-
f[i+L[i]].push_back(i),f[i+R[i]+1].push_back(-i)像這種下標(biāo)有加了值得一定要判斷是否超出范圍 OR 開兩倍數(shù)組。 -
fc[j]*fc[k]>fc[i]哪怕是 long long 也不能隨便乘,注意數(shù)據(jù)可能會(huì)爆。應(yīng)該改用除法。 -
位運(yùn)算的優(yōu)先級低于等號。
-
用快速冪板子小心遇到 \(0\)。
-
函數(shù)返回值類型!!!
-
傳參注意變量類型
-
三分必須是嚴(yán)格單調(diào)。
-
多測題的特判,一定要等所有數(shù)據(jù)輸入完之后再特判,否則會(huì)輸入到下一組去。
-
\(\gcd\) 小心遇到 \(0\)
-
刪 double 改 int 的時(shí)候,一定要注意有沒有一個(gè)地方這個(gè)變量作分母。
-
調(diào)試的時(shí)候如果要注釋語句,一定要在代碼開頭備注,防止最后忘記加上。
-
多組詢問不要隨便改參數(shù)。
-
交互題記得調(diào)用提問函數(shù)的結(jié)果可能要開 long long。
-
Manacher 除了 \(t\) 數(shù)組之外,\(r\) 數(shù)組也要雙倍。
-
必須進(jìn)入型和是否操作型不要放到同一個(gè) if 里面。
-
能預(yù)處理的盡量都預(yù)處理掉,不要中途計(jì)算,可能復(fù)雜度會(huì)增加。
-
多測數(shù)據(jù)清空問題:有的數(shù)組看似不用清空,后面調(diào)用某函數(shù)的時(shí)候會(huì)被覆蓋,但是可能那個(gè)函數(shù)不會(huì)被調(diào)用。
-
vec unique 之后不可 auto
-
每次修改后更新統(tǒng)計(jì)的做法,記得初始的更新統(tǒng)計(jì)。
-
左右端點(diǎn)離散化,記得開兩倍數(shù)組。
-
初始化的時(shí)候小心大小是 \(n\) 還是 \(m\)。
-
任何相乘都要警惕 1ll
-
注意 \(dp_i\) 是否繼承 \(dp_{i-1}\)。有的時(shí)候必須繼承。 P9871 [NOIP2023] 天天愛打卡
-
如果某個(gè)值會(huì)變大,那么注意以它為下標(biāo)的數(shù)組必須開大,不可取初始狀態(tài)。
-
鏈?zhǔn)角跋蛐沁呉_兩倍,如果邊是點(diǎn)的兩倍,那么按照點(diǎn)來開要四倍。
-
前后綴 dp,如果是 \(f_{i-1}+g_i\) 的話注意要枚舉到 \(n+1\)。
-
歐拉回路,數(shù)組大小要開到邊級別,而不是點(diǎn)級別,因?yàn)橐粋€(gè)點(diǎn)會(huì)被經(jīng)過多次。
-
貪心決策中如果一個(gè)物品有多次決策,千萬別在第一次決策完就插入集合,否則可能會(huì)在下次決策的時(shí)候決策自己。P1607 [USACO09FEB] Fair Shuttle G
-
部分分暴力枚舉的時(shí)候記得每次清空,還有 dfs 的時(shí)候注意數(shù)組能不能能開全局。
-
樹 v 圖注意樹上聯(lián)通塊為整體來 dp 的題,需要在塊頂對于所有塊內(nèi)點(diǎn) dp 一下,不然光光是遍歷了某點(diǎn)的子樹不能保證整個(gè)連通塊相連接的點(diǎn)都被訪問過了。
-
少用各種變量的判斷來判斷狀態(tài),而是自己單開一個(gè)狀態(tài)記錄變量。
-
注意更新順序 \(A\to B\),一定要確保 \(A\) 已經(jīng)被更新了。
-
P11191 「KDOI-10」超級演出 有兩個(gè)“序” 的題目一定要想清楚,一個(gè)是圖上的遍歷順序,還有一個(gè)是 \(a\) 序列的順序。
-
一定要注意特殊位置的賦值。
-
給狀態(tài)編號不一定要用 map,可以嘗試用哈希/進(jìn)制之類的。
-
結(jié)構(gòu)體如果比較函數(shù)只比一個(gè)維度的話,放到 map 或者 set 里面如果那一維度相等,那么就默認(rèn)整個(gè)相等了,一定要小心。
-
strlen 的復(fù)雜度是 \(O(n)\) 的,string 后面添加一個(gè)字符也是 \(O(n)\) 的。
-
如果在 dfs 內(nèi)部需要用的一個(gè)局部數(shù)組,那么不能開全局變量,會(huì)導(dǎo)致多層 dfs 重復(fù)使用一個(gè)數(shù)組。
-
1/(int) 需要開 double 或者用 1.0
-
如果用 ull,小心出現(xiàn)負(fù)數(shù),或者先減后加導(dǎo)致中間出現(xiàn)負(fù)數(shù)。
-
修改了某個(gè)地方的返回值,注意可能之前某個(gè)地方有特判返回,也有相應(yīng)修改。
-
樹上一邊 dfs 一邊內(nèi)部用的數(shù)組千萬別用全局。
-
vector 的 resize 函數(shù)里面的賦值是給長度不足的地方賦值的,不是全局。已經(jīng)用過的最好先 clear 再 resize。
-
背包自卷積注意要倒序。
-
字典樹不止 ch 數(shù)組大小要乘以 log,別的和節(jié)點(diǎn)數(shù)相關(guān)的輔助數(shù)組也需要。
-
傳入引用數(shù)組,需要初始化,否則會(huì)出現(xiàn)靈異數(shù)值。
-
答案個(gè)數(shù)可能很大,所以答案數(shù)組大小要注意。
-
全局變量小心在內(nèi)部重復(fù)定義,不會(huì)報(bào)錯(cuò)。
-
/是向 \(0\) 取整,對于負(fù)數(shù)就是向上取整,遇到負(fù)數(shù)和取整的時(shí)候需要格外小心。 -
Dinic 不要忘記調(diào)用 init 函數(shù),尤其是直接套板子的時(shí)候!!
-
多次傳入大數(shù)組很慢!!可以加
const。 -
兩個(gè)內(nèi)外層的 if 如果不打括號,容易會(huì)和后面的 else 產(chǎn)生沖突不知道誰對應(yīng)誰。
-
點(diǎn)分治任何時(shí)候訪問分治中心子節(jié)點(diǎn)的時(shí)候都別忘記判斷 \(vis\) 數(shù)組。
-
有返回值的函數(shù),注意返回值類型是否和返回變量的類型相同。
- 注意,概率期望類題目 \(\sum \dfrac{1}{a_i}\) 的時(shí)候,我們不能算出 \(a_i\) 的期望 \(ave\),然后 \(\dfrac{1}{ave}\),這是錯(cuò)誤的。

浙公網(wǎng)安備 33010602011771號