1. 程式人生 > 實用技巧 >關於演算法競賽某些常見基礎錯誤

關於演算法競賽某些常見基礎錯誤

手(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++式的變數宣告方式(即等到要用的時候再宣告,不要在函式開頭宣告一堆,然後再用)
  • 防禦性程式設計
    • 宣告變數後立即初始化,不管是否必要。
    • 指標不用後立即清空,不管是否必要。

寫在最後

“年代久遠”的緣故,上面的錯誤已經找不到原來的程式碼了。 如果各位刷題時出現鬧鬼程式碼,歡迎編輯在此,以供後人抓鬼。