NOI经验谈
對于NOI來說,甚至比硬實力更加重要。我覺得一場考試這么幾件事要做:看題,選題,分析,編碼,調(diào)試,測試,騙分。
1、看題
拿到試卷以后的第一件事就是看題。看題不是看小說,要仔細閱讀。當(dāng)然,閱讀也不宜過慢,刻意制造緊張的氣氛會極大地影響發(fā)揮。NOI的題目沒有赤裸裸的,都是精心包裝過的,閱讀就是解開這個包裝的過程。首先從題目名看起,認真閱讀問題背景,要明白題目在表達什么意思。一邊閱讀,一邊在腦中建立一個簡單初步的模型。讀完題后立刻看數(shù)據(jù)格式,然后閱讀樣例,如果是圖論題,在紙上把樣例中描述的圖畫出來,手算一下樣例,這樣有助于加深理解題意。這時候不要著急開始想題,把題再讀一遍,第二遍看題可以適當(dāng)加快,但不要放過細節(jié)。
2、選題
除非你是神牛級人物,否則像NOI這樣的比賽你是不可能把題全部想出來的,那么選題就是十分重要的。把所有題先全部看完,對每道題進行簡要的思考,每個題不超過30分鐘,千萬不要陷進去,有思路后即可停止。當(dāng)你有了全局性的認識以后,這時再開始選題。
選題意味著要決定深入思考哪個題,做哪個題,不做哪個題,先做哪個題,后做哪個題。深入思考,當(dāng)然是是要思考已經(jīng)有大致思路的題,在考場上想了半個鐘頭還沒思路的題,再想下去也很難想出來,即便是想出來了,浪費大量時間也是得不償失的。我認為要先做把握大的題,什么是把握大的題?也就是思路完整,算法熟悉,易于調(diào)試的題。這樣的題是拿分的關(guān)鍵,也是和別人拉開檔次的法寶,一般來說一場考試中能有一道就是大幸了。更多的時候,可能會發(fā)現(xiàn)沒有把握很大的題,這時不要著急,靜下心來選擇一道有思路的題深入思考。
如果確定用隨機類算法解決提交答案題,可以先考慮開始寫,這樣在剩下的幾個小時中都可以用來運行隨機程序,以獲得更好的解。
3、分析
有了思路,要開始具體分析一個題的算法。分析前首先要確定一個目標,我是要把這道題AC掉呢,還是拿部分得分足矣?這要看題目的數(shù)據(jù)規(guī)模,把腦中的思路簡要抽象成算法,分析算法的時間復(fù)雜度,確定目標,著手優(yōu)化算法。最后,確定算法的每個細節(jié),思考各種極端的和邊界的條件,把完整的想法轉(zhuǎn)化為完整的算法,在紙上寫出算法的流程,準備編碼。
有時候,并不一定有拿滿分的思路的題就要寫完美的算法,尤其是復(fù)雜的數(shù)據(jù)結(jié)構(gòu)題!這些題經(jīng)常是一個陷阱,令選手陷入其中不能自拔。浩浩蕩蕩寫完二三百行程序,欲調(diào)試出而不能,而樸素的算法花費極少的時間拿到可觀的分數(shù),孰輕孰重還要根據(jù)自己情況來衡量。
4、編碼
在外行人看來,仿佛變成編程序就是信息學(xué)競賽的全部,其實這是很小一部分,但卻是很關(guān)鍵的一部分。編碼細心與否,直接決定了下一步也就是調(diào)試的難度。看著自己在紙上寫出的流程圖,小心地把代碼寫出來。這一步不求快,但求穩(wěn),一定不要犯低級錯誤。建議寫完每個模塊后立即檢查每條語句與所想的是否符合,寫完整個程序后不要急于編譯,先把程序通讀一遍,確認無誤后再開始編譯調(diào)試。
5、調(diào)試
首先用樣例(或自己構(gòu)造的小數(shù)據(jù))測試一邊程序,如果得出了期望的結(jié)果,可以繼續(xù)測試。否則一般會遇到這幾種情況,崩潰、超時、結(jié)果錯誤。崩潰問題一般是這幾種情況的后果:數(shù)組下標越界,訪問無效指針,棧溢出。如果算法可行,那么超時很可能是由無窮遞歸或死循環(huán)造成的。可以使用輸出語句或調(diào)試器跟蹤到程序錯誤的位置,然后檢查有沒有語句邏輯錯誤。如果實在難以發(fā)現(xiàn),可以使用輸出語句,或調(diào)試器單步進入進行跟蹤,發(fā)現(xiàn)異常的部分及時修改。找到結(jié)果錯誤原因,盡量不要一開始就是用單步調(diào)試,不妨把建模過程和程序每步的結(jié)果都輸出,這樣比單步更容易發(fā)現(xiàn)錯誤。
6、測試
調(diào)試和測試是交叉進行的,穩(wěn)定測試無誤后,開始規(guī)模測試。首先要構(gòu)造邊界、極端數(shù)據(jù),因為這些是較容易忽略的死角。接下來,可以考慮隨機數(shù)據(jù)對拍測試(非完美算法可以簡化此步)。首先寫一個樸素程序,要保證正確性,不求運行高效率,然后寫一個數(shù)據(jù)生成器。接下來生成數(shù)據(jù),兩個程序分別運行,對比結(jié)果,反復(fù)大量測試(對拍)。發(fā)現(xiàn)錯誤可以及時調(diào)試并修正,測試可以直到放心為止。充分利用時間,還可以在思考下一道題的時候一邊進行著測試。
7、騙分
會的已經(jīng)寫完的,不會的寫了非完美算法,你還有剩下的工作要做。充分利用NOI的規(guī)則,并不要求算法的完美性,只要能拿到分就是好方法——這一步被人稱為騙分。
騙分,不是胡亂交一個程序,輸出0,IMPOSSIPLE甚至一個隨機數(shù)之類,而是有計劃,有預(yù)謀地搞。騙分的原則就是,盡量避免超時。為什么?超時就是0分,如果不超時地輸出一個結(jié)果,還有可能拿到分。一般來說,對于非完美算法的較大數(shù)據(jù),較好的方法是貪心、卡時和隨機。
貪心法需要大膽的猜想,即使是有反例的錯誤猜想,稍作修改,即可用于應(yīng)付大數(shù)據(jù)。畢竟出題人也未必能考慮的你想到的貪心算法,況且范例也是不容易構(gòu)造的,畢竟隨機數(shù)據(jù)在NOI的測試數(shù)據(jù)中有相當(dāng)?shù)谋戎?#xff0c;貪心是很劃算的。對于需要反復(fù)迭代求最優(yōu)值的算法(例如搜索),不妨采用卡時的方法。因為可能有這種情況,我的程序要運行5秒,但實際上有可能在第1秒以內(nèi)求出的最優(yōu)解已經(jīng)是全局最優(yōu)解,剩下的4秒就是無用的。雖然讀取系統(tǒng)時間time和clock函數(shù)都是禁止直接使用的,我們大可不必真正卡“時”,只需限定一個迭代次數(shù)即可。隨機算法有點撞大運的感覺,其實不是這樣的,較好的隨機算法(例如模擬退火,遺傳算法)得到全局最優(yōu)解的概率相當(dāng)可觀。
8、意外
有時候在考場上會遇到意外,例如寫了半天,發(fā)現(xiàn)算法根本是錯誤的;調(diào)了好長時間都調(diào)不出正確結(jié)果,猶豫是否放棄;精神過于緊張,以至于體力不支;操作系統(tǒng)或環(huán)境出現(xiàn)意外錯誤等等。這些因素都會很大程度上影響發(fā)揮,但當(dāng)我們真正要面對這些問題的時候,該怎么辦?這是一個值得討論的話題,我很難給出一個合適解決方法,但這時候發(fā)揮最重要作用的是心態(tài),良好的心態(tài)才是制勝的最根本條件。
為期一周的特別夏令營結(jié)束了,明天我將從杭州上車返回鄭州,中途可以去西湖玩一玩,保持健康良好的心態(tài)來迎接NOI。我的目標是在NOI上發(fā)揮出我真正的水平,不求金牌,因為我清楚我的實力離金牌還有相當(dāng)?shù)牟罹?#xff0c;愿所有看到這篇文章的同學(xué)們能夠有所幫助,在將要到來的NOI2009和年底的NOIP2009中取得優(yōu)異的成績。
后話:等我正式退役以后,我會寫更多的內(nèi)容,將我的一切經(jīng)驗毫無保留地獻給所有在信息學(xué)競賽路上繼續(xù)奮斗的同學(xué)們。
轉(zhuǎn)載于:https://www.cnblogs.com/tham/p/6827402.html
總結(jié)
- 上一篇: 在Hadoop集群上,搭建HBase集群
- 下一篇: lambda显式声明返回值