ACM比賽技巧

2022-09-07 12:51:10 字數 3189 閱讀 6803

一、語言是最重要的基本功 

無論側重於什麼方面,只要是通過電腦程式去最終實現的競賽,語言都是大家要過的第一道關。亞洲賽區的比賽支援的語言包括c/c++與j**a。筆者首先說說j**a,眾所周知,作為物件導向的王牌語言,j**a在大型工程的組織與安全性方面有著自己獨特的優勢,但是對於資訊學比賽的具體場合,j**a則顯得不那麼合適,它對於輸入輸出流的操作相比於c++要繁雜很多,更為重要的是j**a程式的執行速度要比c++慢10倍以上,而競賽中對於j**a程式的執行時限卻往往得不到同等比例的放寬,這無疑對演算法設計提出了更高的要求,是相當不利的。其實,筆者並不主張大家在這種場合過多地運用物件導向的程式設計思維,因為對於小程式來說這不旦需要花費更多的時間去編寫**,也會降低程式的執行效率。 

接著說c和c++。許多現在參加講座的同學還在上大一,c的基礎知識剛剛學完,還沒有接觸過c++,其實在賽場上使用純c的選手還是大有人在的,它們主要是看重了純c在效率上的優勢,所以這部分同學如果時間有限,並不需要急著去學習新的語言,只要提高了自己在演算法設計上的造詣,純c一樣能發揮巨大的威力。 

而c++相對於c,在輸入輸出流上的封裝大大方便了我們的操作,同時降低了出錯的可能性,並且能夠很好地實現標準流與檔案流的切換,方便了除錯的工作。如果有些同學比較在意這點,可以嘗試c和c++的混編,畢竟僅僅學習c++的流操作還是不花什麼時間的。 

c++的另乙個支援**於標準模版庫(stl),庫中提供的對於基本資料結構的統一介面操作和基本演算法的實現可以縮減我們編寫**的長度,這可以節省一些時間。但是,與此相對的,使用stl要在效率上做出一些犧牲,對於輸入規模很大的題目,有時候必須放棄stl,這意味著我們不能存在「有了stl就可以不去管基本演算法的實現」的想法;另外,熟練和恰當地使用stl必須經過一定時間的積累,準確地了解各種操作的時間複雜度,切忌對stl中不熟悉的部分濫用,因為這其中蘊涵著許多初學者不易發現的陷阱。 

通過以上的分析,我們可以看出僅就資訊學競賽而言,對語言的掌握並不要求十分全面,但是對於經常用到的部分,必須十分熟練,不允許有半點不清楚的地方,下面我舉個真實的例子來說明這個道理——即使是一點很細微的語言障礙,都有可能釀成錯誤: 

在去年清華的賽區上,有乙個隊在做f題的時候使用了cout和printf的混合輸出,由於乙個帶緩衝乙個不帶,所以輸出一長就混亂了。只是因為當時judge team中負責f題的人眼睛尖,看出答案沒錯只是順序不對(答案有一頁多,是所有題目中最長的乙個輸出),又看了看程式發現只是輸出問題就給了個presentation error(格式錯)。如果審題的人不是這樣而是直接給乙個 wrong answer,相信這個隊是很難查到自己錯在什麼地方的。 

現在我們轉入第二個方面的討論,基礎學科知識的積累。

二、以數學為主的基礎知識十分重要 

雖然被定性為程式設計競賽,但是參賽選手所遇到的問題更多的是沒有解決問題的思路,而不是有了思路卻死活不能實現,這就是平時積累的基礎知識不夠。今年world final的總冠軍是波蘭華沙大學,其成員出自於數學系而非計算機系,這就是乙個鮮活的例子。競賽中對於基礎學科的涉及主要集中於數學,此外對於物理、電路等等也可能有一定應用,但是不多。因此,大一的同學也不必為自己還沒學資料結構而感到不知從何入手提高,把數學撿起來吧!下面我來談談在競賽中應用的數學的主要分支。 

1、離散數學——作為計算機學科的基礎,離散數學是競賽中涉及最多的數學分支,其重中之重又在於圖論和組合數學,尤其是圖論。 

圖論之所以運用最多是因為它的變化最多,而且可以輕易地結合基本資料結構和許多演算法的基本思想,較多用到的知識包括連通性判斷、dfs和bfs,關節點和關鍵路徑、尤拉迴路、最小生成樹、最短路徑、二部圖匹配和網路流等等。雖然這部分的比重很大,但是往往也是競賽中的難題所在,如果有初學者對於這部分的某些具體內容暫時感到力不從心,也不必著急,可以慢慢積累。 

競賽中設計的組合計數問題大都需要用組合數學來解決,組合數學中的知識相比於圖論要簡單一些,很多知識對於小學上過奧校的同學來說已經十分熟悉,但是也有一些部分需要先對代數結構中的群論有初步了解才能進行學習。組合數學在競賽中很少以難題的形式出現,但是如果積累不夠,任何一道這方面的題目卻都有可能成為難題。

三、資料結構與演算法是真正的核心 

雖然數學十分十分重要,但是如果讓三個只會數學的人參加比賽,我相信多數情況下會比三個只會資料結構與演算法的人得到更為悲慘的結局。 

先說說資料結構。掌握佇列、堆疊和圖的基本表達與操作是必需的,至於樹,我個人覺得需要建樹的問題有但是並不多。(但是樹往往是很重要的分析工具)除此之外,排序和查詢並不需要對所有方式都能很熟練的掌握,但你必須保證自己對於各種情況都有乙個在時間複雜度上滿足最低要求的解決方案。說到時間複雜度,就又該說說雜湊表了,競賽時對時間的限制遠遠多於對空間的限制,這要求大家盡快掌握「以空間換時間」的原則策略,能用雜湊表來儲存的資料一定不要到時候再去查詢,如果實在不能建雜湊表,再看看能否建二叉查詢樹等等——這都是爭取時間的策略,掌握這些技巧需要大家對資料結構尤其是演算法複雜度有比較全面的理性和感性認識。

接著說說演算法。演算法中最基本和常用的是搜尋,主要是回溯和分支限界法的使用。這裡要說的是,有些初學者在學習這些搜尋基本演算法是不太注意剪枝,這是十分不可取的,因為所有搜尋的題目給你的測試用例都不會有很大的規模,你往往察覺不出程式執行的時間問題,但是真正的測試資料一定能過濾出那些沒有剪枝的演算法。實際上參賽選手基本上都會使用常用的搜尋演算法,題目的區分度往往就是建立在諸如剪枝之類的優化上了。 

常用演算法中的另一類是以「相似或相同子問題」為核心的,包括遞推、遞迴、貪心法和動態規劃。這其中比較難於掌握的就是動態規劃,如何抽象出重複的子問題是很多題目的難點所在,筆者建議初學者仔細理解圖論中一些以動態規劃為基本思想所建立起來的基本演算法(比如floyd-warshall演算法),並且多閱讀一些定理的證明,這雖然不能有什麼直接的幫助,但是長期堅持就會對思維很有幫助。

3、zoj: 

zoj是浙江大學建立的online judge,是中國大學建立的第乙個同類站點,也是最好和人氣最高的乙個,筆者和許多班裡的同學就是在這裡練習。zoj雖然也定位為乙個英文**,但是這裡的中國學生比較多,因此讓人覺得很親切。這裡目前有500多道題目,難易分配適中,且涵蓋了各大洲的題目型別並配有索引,除此之外,zoj的judge系統是幾個**中表現得比較好的乙個,很少出現wrong answer和presentation error混淆的情況。這裡每月也辦有一次網上比賽,只要是註冊的使用者都可以參加。 

說起中國的online judge,去年才開始參加acm競賽的北京大學現在也建立了自己的提交系統;而我們學校也是去年開始參加比賽,現在也有可能推出自己的提交系統,如果能夠做成,到時候大家就可以去上面做題了。同類**的飛速發展標誌著有越來越多的同學有興趣進入資訊學的領域探索,這是一件好事,同時也意味著更激烈的競爭,希望大家都能通過競爭鍛鍊自己、提高自己,並爭取成為勝利者。

ACM比賽經驗

1.比賽中評測會有些慢,偶爾還會碰到隔10分鐘以上才返回結果的情況,這段時間不能等結果,必須開工其他題,如果wa,兩道題同時做。交完每道題都要先列印。2.比賽時發的飯不是讓你當時就吃的,那是給你賽後吃的。基本上比賽中前幾名的隊都沒人吃,除非領先很多。3.很多選手,尤其是第一次參加比賽的,到乙個新環境...

關於ACM比賽的感悟

忙活了乙個月,終於比賽完了!不知不覺,已經參加兩次acm的比賽了,雖然有些打醬油的感覺!結果其實已經是在預料中了,但我依然享受了訓練的過程。乙個月過得真的是很讓人困惑,有時候,乙個演算法可以連續糾結三天而對它沒有任何的感覺。有時候,別人的一種實現讓我有種想 的感覺。我掛在嘴邊最多的一句話就是 想出那...

ACM 數論 博弈 (比賽用)

1.bash博弈 巴什博弈 只有一堆n個物品,兩個人輪流從中取物,規定每次最少取乙個,最多取m個,最後取光者為勝。if n m 1 0 cout 後手必勝 2.威佐夫博弈 wythoff game 有兩堆各若干的物品,兩人輪流從其中一堆取至少一件物品,至多不限,或從兩堆中同時取相同件物品,規定最後取...