常見錯誤總結

少打頭文件

少打using namespace std;

命名沖突,全局變量與局部變量命名一致,導致使用的值不是期望值

邊讀邊寫,導致改后讀,覆蓋寫入的值

長整數移位溢出,1<<63是錯誤的,應該寫成1ll<<63

循環變量打錯,i打成j? 犯錯次數加一

乘法溢出導致的,數組下標正溢出或負溢出

dfs時,開頭沒有vis[start]=1;

bfs時,狀態維數開少

bfs時,少寫了vis[node]=1或者少寫了Q.pop導致的MLE

解同余方程時,不先約去GCD的話,解的距離就是a/GCD或b/GCD,先約了的話,那么需要原方程的值的時候就需要帶入a,而不是已經改變的a/GCD

做exgcd的題目一定要小心ans%mod==0的情況

(N-ans)/y+1 如果ans==0,則1不應該加

公式不能只考慮第一個元素,其他元素也要全部列出來

單調隊列總是忘了取元素,直接把隊列中的下標拿出來用

vector的resize不會釋放內存,之前的值都還在...

二重循環里容易把=寫成+=

?INF值不夠大

char數組放了過大的值

char數組結尾不是'\0'

當要改變一系列聲明變量的類型時。。。如果不小心在回車換行時,把大數據類型改成了小數據類型,則會發生溢出。或者ub

比如int-->bool 結果不斷加一他還是一

?

然后就是下標i,j容易弄混,在內循環容易仍然使用i,或者使用常量

?

然后平常容易邏輯寫反比如while(a!=NULL&&b!=NULL)和while(!a&&!b)這兩個看起來很像,但是邏輯上是相反的

?

然后就是編程范式。。。也叫循環不變式,這個一定要想好,是最前面初始化推最后,還是先計算最后考慮結尾

?

?數組名稱寫錯,傳的參數一直不變,或者臨時參數一直沒有還原

?

不能整除導致的加一和(int)(divison expr+0.5)是不一樣的。。。。

?

還有一道雪崩的大數題目:http://www.cnblogs.com/linkzijun/p/6106697.html

?

https://www.jisuanke.com/article/po3pm3e6

?下面調試程序的技巧轉自計蒜客

作者介紹:計蒜客研發工程師,畢業于西南科技大學,曾獲 ACM/ICPC 亞洲區預賽金獎。

代碼能力是我們在程序設計競賽中常常談到的一種能力,是指選手把算法用代碼準確地實現的能力。

2005 年,Comars 曾經給代碼能力作過一個比較準確的定義:如果我?150150?行以內的題目,1Y(提交一次就正確通過,Y 是指 Yes)率非常高,并且保持穩定;而當代碼長度超過?150150?行以后,1Y 率就開始急速下降了。如果我們畫出一條代碼行數與 1Y 率之間的關系的曲線,150150?行就是一個轉折點。我們不妨認為,150150?行就是 Comars 當時的代碼能力。一年以后,經過努力,Comars 把代碼能力提高到了?250250?行,也就意味著他通常可以無錯誤地寫出一份?250250?行的代碼。

當然,想要把代碼能力提高到?150150?行并非是一個簡單的事情。在代碼能力不夠強的時候,就需要有足夠的調試(debug)能力了。結合我的比賽經歷和平時訓練的經驗,給大家分享一些程序設計競賽題目 debug 的技巧。

在開始 debug 之前,要先在腦海中過一遍思路,必須保證自己有一個清晰的算法思路和一個正確的算法(至少自己要相信它是正確的)。一定要有清晰的思路,不然寫出來的代碼可能連自己都看不懂;而基于一個錯誤算法的 debug 是毫無意義的。當你確認了上面兩件事情以后,才有必要開始 debug。

1) 順著你的思路仔細閱讀自己的代碼兩到三遍,注意是仔細,要一句一句地讀。核對你的代碼和你的思路是否一致,不要放過任何一個小細節。如果遇到拿不準的地方,立刻停下來仔細想想,直到想清楚以后再繼續。在這個過程中,往往可以找到很多低級錯誤,尤其是對于代碼能力不太好的同學,比如——變量打錯、代碼寫錯位置、變量賦值錯誤等等。靜態閱讀代碼的效率是非常高的,因為往往讀一份自己寫出的代碼的時間遠小于寫的時間——既然都已經花了那么多時間寫出來了,何必還在乎這點時間多讀幾遍呢。

2) 如果經過上面的過程還沒有找到程序中的錯誤,或者找到了一些問題但是程序的結果還是不對,這時我們就要通過運行程序來 debug。根據我以往參加競賽的經驗,經過上面的過程基本上可以解決一半以上的問題。如果一定要走到這一步,很可能已經給自己挖了一個巨大的坑。想要通過運行程序來 debug,第一步是需要拿到一組能使得程序出錯的數據,拿到錯誤數據以后,debug 就成功了一半。在造錯誤數據時,一定要靜下心來耐心出,不要指望一下就能造出錯誤數據。并且造出的數據盡量不要規模太小、太簡單,數據越復雜,找到錯誤的概率會越高。對于 ACM/ICPC 這種團隊比賽,必要的時候你可以讓隊友幫你造數據。例如某年 ACM/ICPC 沈陽賽區,我當時調試一道模擬題半個多小時還是錯的,距離比賽結束還有?1010?分鐘時,隊友找到一組錯誤數據,然后我調了?55?分鐘就找出了那個致命的 bug。在比賽進行到?295295?分鐘(比賽一共?300300?分鐘)的時候正確通過了這題(很關鍵的一題)。同年上海賽區,也是最后幾分鐘隊友給出一組給力數據,在?299299?分鐘絕殺一道 dp 題目。有了數據以后,剩下的調試應該很簡單了。根據錯誤數據,輸出一些重要的中間變量的值,然后觀察是否和預期一樣。這里也可以借助二分思想輸出中間變量,快速定位到錯誤代碼塊。不過實踐中,通常是根據經驗,覺得哪塊容易出錯就重點輸出哪一塊的變量。無論是平時訓練還是比賽中我都建議少用 IDE 斷點調試功能和單步調試功能,通常比較浪費時間。

3) 對于某些特殊題目,小數據可以很容易寫出一個時間效率低但確保正確的“暴力”程序。這時候,我們可以用暴力程序和出錯程序對拍。對于造出的一些小數據,同時用自己的程序和暴力程序得出答案然后對比。這個小數據的范圍是暴力程序能在短時間內得到正確結果的最大范圍。因為暴力程序一般都很簡單,沒那么容易寫錯,所以你通常把暴力程序當成小數據的標準程序。如果連暴力都寫錯,建議多做練習,提高代碼能力,確保短代碼都能盡量做到零失誤。

經過上面的 debug 過程以后,如果你手造的復雜數據多達?1010?組以上還沒有發現錯誤。你可以嘗試下面的做法:

  1. 重新思考一個新思路,或者嘗試去發現原思路中的問題。

  2. 先靜下心來,先看看其他題,AC 一些其他題調整一下狀態,然后回來重新 debug。

  3. 如果你確定思路一定沒問題,代碼也一定沒錯,那通常是因為你讀錯題目了,重新回去讀題。

  4. 如果到這一步你的程序還是無法正確通過,并且你確保沒讀錯題,只要有足夠的自信,聯系出題人,和他確認數據是否有問題。

debug 過程中不要輕易請教別人,請教別人思路沒問題,但是請教別人幫你 debug 不太好。除非你已經連續 debug 了一天還沒有發現錯誤,再考慮去請教其他人。這里教大家一個 debug 技巧——斷言(assert)。

1
assert(x >= 0);

如果x >= 0不成立,則程序會因為運行錯誤而退出。比如寫一個整數除法函數:

1
int division(int x, int y) {
2
    assert(y != 0);
3
    return x / y;
4
}

如果y == 0程序就會異常退出,你一定是在程序的其他什么地方寫錯了。

再如,solve(x, y)如果應該等于solve(y, x),我們可以assert(solve(x, y) == solve(y, x)),如果運行錯誤,那么必然solve寫錯了。在解決 Polya 計數題目的時候,可以assert(sum % |G| == 0)。除了用來調試以外,assert還可以用來驗證數據是否規范,對出題人很方便,還可以用來驗證 OJ 數據的準確性。

經驗之談

最后列出一些比賽和訓練中特別容易犯的一些低級錯誤和治療方法:

  1. 錯誤代碼

    1
     int n;
    2
     int a[n];

    治療方法:初學者很容易寫出這樣的代碼,當然老隊員肯定寫不出這種代碼的。盡量避免這種寫法,定義數組用常量,比題目約定的數據范圍稍微大一點。比如數據范圍是?1 \leq n \leq 100001n10000,則開一個?10000 + 1010000+10?的數組會比較穩妥,因為你也許后來心血來潮讓下標從?11?開始計數。

    1
     const int maxn = 10000 + 10;
    2
     int a[maxn];
  2. 錯誤代碼

    1
     for (int i = 0; i < n; i++) {
    2
         if (i = n) {
    3
             printf("%d\n", i);
    4
         }
    5
         else {
    6
             printf("%d ", i);
    7
         }
    8
     }

    治療方法:剁手。編譯警告(warning)會提醒的,不要忽略甚至直接關閉編譯警告。建議在做題的時候把編譯選項-Wall打開:

    1
     g++ -Wall -o main main.cpp
  3. 錯誤代碼

    1
     double a = 1 / 3 * 3;
    2
     double b = 1;
    3
     if (a == b) {
    4
         printf("Yes");
    5
     }

    治療方法:判斷浮點數相等應該用極小值eps來輔助,一般eps1e-8足夠了,確保比題目約定的精度誤差要求更小。

    1
     const double eps = 1e-8;
    2
     double a = 1 / 3 * 3;
    3
     double b = 1;
    4
     if (fabs(a - b) < eps) {
    5
         printf("Yes");
    6
     }
  4. 錯誤代碼

    1
     const int inf = 0x7fffffff;
    2
     int dp[10];
    3
     int main() {
    4
         for (int i = 0; i < 10; ++i) {
    5
             dp[i] = inf;
    6
         }
    7
         for (int i = 1; i < 10; ++i) {
    8
             dp[i] = min(dp[i], dp[i] + dp[i - 1]);
    9
         }
    10
         return 0;
    11
     }

    治療方法:這里inf + inf會溢出,超出了int的范圍。可以把inf的定義改成:const int inf = 0x3fffffff,就可以確保不會溢出了。順便給大家推薦一個小技巧:

    1
     int dist[100];
    2
     memset(dist, 0x3f, sizeof(dist));

    如上的代碼可以讓dist數組中的所有元素賦值為0x3f3f3f3f,并且兩個初始值相加也不會溢出,常用于圖論或動態規劃中數組的初始化。

  5. 錯誤代碼

    1
     // 1. 線段樹 build
    2
     void build(int id, int l, int r) {
    3
         if (l == r) {
    4
             return;
    5
         }
    6
         int mid = (l + r) >> 1;
    7
         build(id << 1, l, mid);
    8
         build(id << 1 + 1, mid + 1, r);
    9
     }
    10
     // 2. 取 dp 答案
    11
     printf("%d\n", dp[1 << n - 1]);

    治療方法:沒有弄清楚操作符優先級。在優先級不確定的情況下,用小括號來明確指定優先級能夠避免這類問題的發生。當然,最好還是要弄清這些符號之間優先級的關系。

    1
     // 1. 線段樹 build
    2
     void build(int id, int l, int r) {
    3
         if (l == r) {
    4
             return;
    5
         }
    6
         int mid = (l + r) >> 1;
    7
         build(id << 1, l, mid);
    8
         build(id << 1 | 1, mid + 1, r);
    9
     }
    10
     // 2. 取 dp 答案
    11
     printf("%d\n", dp[(1 << n) - 1]);
  6. 錯誤代碼

    1
     #define MAXN 1000 + 10
    2
     #define MULTIPLY(x, y) x * y
    3
     int a[MAXN * 4];
    4
     int main() {
    5
         int x = MULTIPLY(1 + 2, 3);
    6
         return 0;
    7
     }

    治療方法:盡量不要用宏定義,常量用const來定義。宏定義雖然很方便,但是用起來很容易出錯,比如上面這段代碼。如果你一定要用宏定義,先去了解宏定義常見的“坑”再用。

  7. 錯誤代碼

    1
     #include <iostream>
    2
     using namespace std;
    3
     bool t, first;
    4
    ?
    5
     int main() {
    6
         first = true;
    7
         cin >> t;
    8
         while (t--) {
    9
             ...
    10
         }
    11
         return 0;
    12
     }

    治療方法:寫代碼的時候不要太“隨性”,這種情況的發生通常都是寫程序時中途加了一個變量導致的,只要不太粗心就能避免。由于可能會發生這類錯誤,所以在本地造數據的時候,對于多組數據的題目要盡可能在一次測試中多造幾組數據,以盡量避免此類問題。

  8. 在大多數平臺和 ACM/ICPC 現場賽時,C++ 的 long long 用%lld輸入;而對于一些搭建在 Windows 上的 OJ(如 Codeforces、HDOJ),要用%I64d讀入。具體使用哪個占位符要多看?FAQ。

  9. 變量在訪問前一定要初始化。好的習慣是在定義一個變量的時候就立刻初始化。一定注意,很多平臺(包括計蒜客的題庫)的編譯器是不會在定義數組后將數組內元素全部初始化為?00?的,如果你遇到本地和線上結果不一致的情況,可以從這個方向來找問題。

  10. 避免訪問非法內存。訪問非法內存的事情經常發生,但是可以通過養成好習慣來避免。比如stackqueueset訪問之前必須先確認不為空;訪問指針之前確保指針不是野指針;數組內存開得足夠大,等等。

轉載于:https://www.cnblogs.com/linkzijun/p/6783103.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/254731.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/254731.shtml
英文地址,請注明出處:http://en.pswp.cn/news/254731.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

x264_sps_init

x264_sps_init此函數為序列量化集的初始化。主要對結構體x264_sps_t中參數的初始化。 void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param ) { sps->i_id i_id;首先設置序列參數集的ID b_qpprime_y_zero_transform_bypass判斷碼率控制方法是否是恒定質量…

HALCON相機標定相機內參相機外參

目錄相機標定1.相機標定是什么2.怎么使用halcon進行相機內外參標定&#xff1f;&#xff08;1&#xff09;搭建硬件1.**相機連好電腦&#xff0c;用相機廠家軟件打開相機&#xff0c;檢查一下相機是否正常。**2.**接下來使用halcon連接相機**&#xff08;2&#xff09;開始標定…

ionic更改端口號

ionic serve -p 8888 —— 重新指定端口號為8888 serve [options] ............................... 啟動本地服務器進行開發測試 dev/testing   [--consolelogs|-c] ..................... 輸入app的控制臺到ionic的控制臺顯示   [--serverlogs|-s] .....................…

angular change the url , prevent reloading

http://stackoverflow.com/questions/14974271/can-you-change-a-path-without-reloading-the-controller-in-angularjs $location.search({vln: $scope.vln_id}, false);會改變url中 &#xff1f; 后面的 搜索參數&#xff0c;但是controller不會重新實例化。angular 官方文檔…

Ubuntu apt-get 更新/查看軟件

ubuntu 升級軟件&#xff1a; sudo apt-get update 更新源  sudo apt-get upgrade 更新已安裝的包  sudo apt-get dist-upgrade 升級系統 ubuntu升級特定軟件&#xff1a; 可以用 sudo apt-get install pkgname 看軟件安裝位置:dpkg -L xxxx 查看軟件是否安裝&#xff1…

X264設定

--aq-mode <integer> AQ method [1]- 0: Disabled- 1: Variance AQ (complexity mask)說明&#xff1a;自適應量化方法&#xff0c;可以改善某些場景過于模糊等問題&#xff0c;默認開啟- 0: 關閉- 1: 可變AQ推薦值&#xff1a;默認范例&#xff1a;--aq-mode 1--aq-stre…

C#圓形卡尺測量程序基于halcon

廢話不多說上源碼 覺得帖子有用給點個贊哈 先來個效果圖 下邊的是源碼&#xff0c;自己新建一個文件粘貼進去&#xff0c;包含到您現在的項目 中。這串源碼后邊是使用方法。 using System; using System.Collections.Generic; using System.Linq; using System.Text; usin…

MySQL松散索引掃描與緊湊索引掃描

什么是松散索引&#xff1f; 答&#xff1a;實際上就是當MySQL 完全利用索引掃描來實現GROUP BY 的時候&#xff0c;并不需要掃描所有滿足條件的索引鍵即可完成操作得出結果。 要利用到松散索引掃描實現GROUP BY&#xff0c;需要至少滿足以下幾個條件&#xff1a;◆ GROUP BY 條…

算法馬拉松24

算法馬拉松24 A 小C的多邊形 題意&#xff1a;n1個點的多邊形。給外圈的邊標記上1~n&#xff0c;里圈的邊也標記上1~n&#xff0c;使得對于一個外圈相鄰點與中間點構成的三角形的邊權之和都相等。\(n \le 10^6\) 題解&#xff1a;顯然每個三角形權值和為\(\frac{3(n1)}{2}\) 一…

HUD2795 線段樹(單點更新)

題目中給出的h和w范圍均大&#xff0c;其實n的最大范圍才200000&#xff0c;所以我們建立的線段樹大小為min(h,n),線段樹的每一個節點包含一個變量c&#xff0c;記錄當前區間內還剩下的可以put on的最大長度。插入一個數時&#xff0c;如果該數大于該區間最大值&#xff0c;則返…

科維PLC運行時系統ProConOS embedded CLR 2.2 特定應用

ProConOS embedded CLR是新型的開放式標準化PLC運行時系統&#xff0c;符合IEC 61131標準&#xff0c;可執行不同的自動化任務&#xff08;PLC、PAC、運動控制、CNC、機器人和傳感器&#xff09;。   通過采用國際標準的微軟中間語言&#xff08;依據IEC/ISO 23271標準為MSIL…

linux下vi命令大全

進入vi的命令 vi filename :打開或新建文件&#xff0c;并將光標置于第一行首 vi n filename &#xff1a;打開文件&#xff0c;并將光標置于第n行首 vi filename &#xff1a;打開文件&#xff0c;并將光標置于最后一行首 vi /pattern filename&#xff1a;打開文件&…

set()與get()詳細解答(C#)

這幾天在搬磚時候用到了set()與get()&#xff0c;同事問了我一些問題&#xff0c;我打算在博客中總結一下。 覺得幫助到了您&#xff0c;幫我點個贊哦。 屬性訪問器 其實說白了就是操作一個屬性&#xff0c;更通俗一點說就是對一個變量的取值與賦值。 先來看get() get 訪問…

IM應用中如何計算富文本的高度

背景 在開發IM的項目過程中&#xff0c;經常會有出現一些需要計算DOM高度&#xff0c;然后超出若干行隱藏等需求。很多時候&#xff0c;需要計算高度的DOM元素都是動態生成的&#xff0c;我們無法在數據渲染前獲取到它的高度。 如果沒有任何交互&#xff0c;我們可以通過CSS來實…

G代碼 機器人的CNC實現

&#xfeff;  控制銑削工作臺和工件的NC程序&#xff0c;通過CAD軟件創建&#xff0c;這些NC程序與特定的機器類型相關。 NC程序在笛卡爾坐標系中動作的描述&#xff0c;對于需要確保一個明確的變換軸位置的關節型的機器人來說&#xff0c;缺少附加的狀態和旋轉信息。傳…

IScroll5中文API整理,用法與參考

IScroll是移動頁面上被使用的一款仿系統滾動插件。IScroll5相對于之前的IScroll4改進了許多&#xff0c;使得大家可以更方便的定制所需的功能了。 做項目的時候正好用到了這個插件&#xff0c;自己做了一下總結&#xff0c;發在這里方便大家學習IScroll5。 官網&#xff1a;htt…

Linux?安裝USB攝像頭

sudo apt-get updatesudo apt-get install fswebcamsudo apt-get install mplayersudo apt-get install alsamixer安裝完畢ls /dev查找設備是否有video0這個設備sudo mplayer tv:// 可以看到攝像內容轉載于:https://www.cnblogs.com/smartkeke/p/6820426.html

struct x264_t 維護著CODEC的諸多重要信息

//x264_t結構體維護著CODEC的諸多重要信息struct x264_t{/* encoder parameters ( 編碼器參數 )*/x264_param_t param;x264_t *thread[X264_SLICE_MAX];/* bitstream output ( 字節流輸出 ) */struct{int i_nal;x264_nal_t nal[X264_NAL_MAX];int i_bitstr…

如何判斷一條曲線是否自己相交?

今天看到群里有人在問這個問題&#xff0c;想了一個解決辦法。 我們首先作假設&#xff0c;如果一條曲線有交點&#xff0c;那么它就是相交的對吧。可能大家想的都是這樣&#xff0c;就開始找各種方法去識別交點。 我們換個角度想一下&#xff1a;是不是我們判斷這條曲線是否帶…