**自:
資訊學之於其他競賽學科的不同,就在於需要通過寫程式來表達自己的思維和想法。如何盡可能又快又好地除錯程式,成了我們必須要思考的問題。相信很多同學都有過這樣的經歷:思考乙個演算法只花了半個小時,但是把這個演算法寫對卻花了一天。。思考與實現的時間往往不成正比。
關於除錯有乙個大前提,就是思考的方向一定得嚴謹正確,因為思考決定實現,如果思考的時候有漏洞,那麼實現的程式肯定也不強健。在想出演算法之後不要急著實現,一定要認真反覆地論證:我的演算法每一步的定義是否嚴謹,是不是**還有漏洞,我的演算法所得到的東西是否就是題目需要求解的。確認了自己的想法後再開始實現。
假設我們現在寫完了乙個程式:
第一步:靜態查錯(俗稱裸眼觀察^_^),即不測試資料,而是通過反覆地看**來檢查。靜態查錯首先要檢查是否有變數名打錯,語法是否正確,你打的**和你的想法是否相符。然後要分析**的邏輯性是否嚴謹正確,是否能在所有情況下都能正確執行。最後還要驗證是否在所有邊界情況都能得到正確的解,包括陣列是否開夠,會不會有n=0的情況等等。靜態查錯是最有效的查錯方法,為什麼有的大牛能夠一遍寫對很複雜的**,因為他們靜態查錯的能力非常之強,並且在敲程式的過程中就已經在靜態查錯了。在實踐中,我建議大家盡量讓自己的程式模組化(即乙個函式做一件事情),然後檢查的時候邊看邊打上注釋,這樣能讓自己更清醒地判斷,也方便以後能輕鬆閱讀自己的程式。
第二步:動態查錯,用資料來驗證**的正確性。人眼往往不可靠,我們需要用更安全的資料來判定。一般而言在普通的oi競賽中,時間是比較充裕的,我們有時間來對拍。對拍需要三個程式,乙個是你需要提交的標準程式(std),乙個是能夠通過部分資料的暴力程式(plain),乙個是用來生成資料的程式(mk_data)。
關於plain程式,一般會比較好寫,所以一定要認真檢查,不要寫錯!
關於mk_data,一般需要得到乙個隨機的整數,c++語言寫法如下:
我們可以執行一次mk_data,得到一組資料,然後分別用std和plain跑一遍,看結果是否一樣。當然這樣手動是比較麻煩的,我們可以用指令碼來自動對拍,下面是windows下用bat指令碼對拍的普通寫法:
(約定plain的輸出檔案是1.out,std的輸出檔案是2.out)
將這一段話寫在乙個文字檔案中,將其重新命名為ck.bat,然後和上述三個程式放在同一資料夾下,雙擊ck.bat,就能夠實現對拍了。對拍的優勢在於能夠近似模擬出出題人的資料來檢驗你的程式,一般在考場上通過了對拍的程式很難寫掛。當然有的時候隨機資料不一定能夠滿足我們的需求,這時候需要我們從出題人的角度出發,去構造一些最壞情況下的資料,來檢驗我們程式的強健性。
第三步:提交之前,檢查檔名,再次編譯程式,執行一遍樣例,以防手抽。
靜態差錯大大降低了程式出錯的概率,減少了動態除錯的時間,動態查錯給程式上了雙保險,最後的檢查防止了意外情況的出現。這樣的程式的正確性能夠大大提高。
在除錯中,最關鍵的一點,是站在邏輯的高度去思考程式,而不是從某個資料的角度去檢視變數,這樣才能避免陷於除錯的泥潭不能自拔。
對資訊學競賽中除錯方法的建議
資訊學之於其他競賽學科的不同,就在於需要通過寫程式來表達自己的思維和想法。如何盡可能又快又好地除錯程式,成了我們必須要思考的問題。相信很多同學都有過這樣的經歷 思考乙個演算法只花了半個小時,但是把這個演算法寫對卻花了一天。思考與實現的時間往往不成正比。關於除錯有乙個大前提,就是思考的方向一定得嚴謹正...
資訊學競賽刷題建議歷程
廖叔叔部落格 1 近10年noip普及組前三題 30道題練入門 2 usaco全體 練基礎演算法 3 近10年noip提高組全部試題 感受oi基礎 3.1 劉汝佳白書訓練指南所有例題 打好基礎 4 開始sgu版切刷題 不管苦難與否直接掃蕩過,這個過程一直伴隨你到全國賽,最好題量破300 5 hnoi...
資訊學競賽刷題建議歷程
1 近10年noip普及組前三題 30道題練入門 2 usaco全體 練基礎演算法 3 近10年noip提高組全部試題 感受oi基礎 3.1 劉汝佳白書訓練指南所有例題 打好基礎 4 開始sgu版切刷題 不管苦難與否直接掃蕩過,這個過程一直伴隨你到全國賽,最好題量破300 5 hnoi近10年試題 ...