關於演算法競賽某些常見基礎錯誤
阿新 • • 發佈:2020-12-01
手(shou)誤(jian)
-
出錯特徵:程式執行流程出乎意料,結果不正確。
-
出錯樣例:
for (int i = 0; i < n; i++) { if (i = n) printf("%d\n", i); else printf("%d ", i); }
-
治療方法:剁手。多剁兩次就記住了。
浮點數判等
-
出錯特徵:WA到死。
-
出錯樣例:
double a = 1 / 3 * 3; double b = 1; if (a == b) { printf("Yes"); }
-
治療方法:
const double eps = 1e-5; double a = 1 / 3 * 3; double b = 1; if (abs(a - b) < eps) { printf("Yes"); }
-
注意點:eps到底取多少? 一般在1e-5到1e-8之間。有些題目卡eps。(就是莫名其妙的一個wa一個ac)
宣告變數和使用變數太遠……
-
出錯特徵:Output Limit Error 或 WA 或 RE 或 TE 或 機器爆炸。
-
出錯樣例:
題目:計算a+b。
輸入:t組資料,每組測試資料包含兩個數a,b。
輸出:對於沒組資料,輸出a+b的值。每兩組輸出之間換行隔開
-
#include <cstdio> bool isFirst, t; int a, b; int main() { isFirst = true; scanf("%d", &t); while (t--) { scanf("%d%d", &a, &b); if (isFirst) { isFirst = false; } else { puts(""); } printf("%d\n", a + b); } return 0; }
資料: 3 1 2 2 3 3 4
-
治療方法:先睡一覺。寫出這種程式碼,你一定是太累了。
忘記初始化
- 出錯特徵:WA
- 出錯樣例:比如每次使用vis之前沒有清false之類。
- 治療方案:
- 每個變數定義的同時就初始化。
- 提交程式碼之前,檢查所有定義的變數是否已經初始化。
陣列開小了
- 出錯特徵:差別不大的會WA或TE。差別大的會RE。
- 出錯樣例:眼花手抖導致的陣列少個0。,“樹”類問題陣列只開了n(應該要4n)
- 治療方案:陣列開的足夠大。
Ctrl+C && Ctrl+V
- 出錯說明:複製一段程式碼然後貼上再修改的方式程式設計。常常出現沒修改乾淨的問題。常出現在搜尋題或輸出圖形的題。
- 出錯特徵:WA
- 出錯樣例:暫缺
- 治療方法:
- 不要複製程式碼。把能重用的地方封裝成函式然後再用(往往比較費時間)
- 採用複製程式碼方式。修改後然後檢查3遍,當WA的時候,重點檢查此處。優先重寫此處。(即將複製的程式碼列為高危程式碼)
- PS:寫工程的時候,不要複製程式碼……除非你的工程不需要維護(比如作業)
建議的程式碼書寫方式
- 良好的程式碼風格。包括但不限於
- 有意義的變數名(起名字真的是個技術,沒那麼簡單,就能找到,
聊得來的伴) - 縮排
- 大括號的位置(選擇一個風格保持統一)
- 有必要的空格使程式碼清晰(比如:
int a = (10*3/2 + 10)/3
) - C++式的變數宣告方式(即等到要用的時候再宣告,不要在函式開頭宣告一堆,然後再用)
- 有意義的變數名(起名字真的是個技術,沒那麼簡單,就能找到,
- 防禦性程式設計
- 宣告變數後立即初始化,不管是否必要。
- 指標不用後立即清空,不管是否必要。
寫在最後
“年代久遠”的緣故,上面的錯誤已經找不到原來的程式碼了。 如果各位刷題時出現鬧鬼程式碼,歡迎編輯在此,以供後人抓鬼。