1. 程式人生 > >ACM到底該不該堅持??

ACM到底該不該堅持??

別人(感覺很牛逼的樣子)的經歷:

首先就是我為什麼要寫這麼一篇日誌。原因很簡單,就是因為前幾天有個想起步做ACM人很誠懇的問我該如何入門。其實就現在而言,我並不是很想和人再去討論這樣的話題,特別是當我發現我有很多的東西要學的時候,我實在是不想花太多的時間在這種問題上。但是我當年也是純憑熱情搞ACM過來的,實在是不忍心打擊一個同樣有著滿腔熱情的起步者。所以乾脆就多花點時間,總結一下我的一些觀點和看法,以後再讓人問起這個問題的時候,也好不用再重複什麼了。



其次,我在這篇文章中並不打算探討特別細節的問題,比如說如果某些人想從中得到諸如“該看哪本書入門比較好”或者“動態規劃、搜尋、圖論該怎麼學”之類問題的答案,恐怕要讓您失望了。我覺得書和方法都是因人而異,對自己最好的方法需要靠自己去摸索,抄別人是抄不來的。更何況當初我起步的時候也幾乎是一個人單幹,沒什麼人推薦好書之類,都是搜到哪本書裡有我想看的東西然後就抓過來看,感覺不行就再換一本。很多眾口相傳的好書,我第一次看的時候,其實裡面絕大部分的內容我已經都學過了,所以這種書籍對初學者的作用,我本人並沒有切身的體會,而且也沒有過相關的教學經驗,所以不敢隨意評價。


再次,本文很多觀點僅僅從是個人經歷和想法總結出來的,我對教育這方面也並沒有什麼研究,所以沒什麼體系化,內容非常山寨,僅供參考。


最後,這可能是一篇非常低端的文章,希望大家不要抱著什麼很大的期望,免得到時失望更大。不足之處,還望諒解。


 


為什麼要做ACM?


這個題頭可能有些歧義。我這裡並不是想要宣傳ACM有多好,而是我希望每一個想參加ACM的人先問一問自己這個問題:我為什麼要參加ACM?我想從ACM的鍛鍊中得到什麼?


在我看來,這個問題的最好的答案是“因為做ACM很爽”。當你埋頭苦讀你千辛萬苦蒐集到的各種資料,終於學會了某演算法並用它A了一道連XX大牛都沒有做出來的題時,你覺得很爽;當你埋頭苦思數日,突然靈光一現想到解法,一下AC,多日積鬱一掃而空,你覺得很爽;當你看完一道題之後,行雲流水般的在鍵盤上敲著程式碼,一遍通過sample並AC,你覺得很爽,就行了。


或許有人會問,搞ACM能找到好工作嗎?是可以。但我覺得如果你真的想找到好工作,你應該多去外面實習,多做幾個專案積累經驗,而不是來搞什麼ACM。搞ACM能對學術有幫助麼?確實有。但是如果你真的想做學術,你應該早點進個實驗室,或者爭取去MSRA實習,或者自己多研究一些前沿的學術論文,而不是來搞什麼ACM。搞ACM對保研加分有幫助麼?是有。但是你不覺得數學建模什麼的會比ACM更有幫助麼?


當然我要承認的是,大多數ACMer除了爽之外,確實收穫了很多其他的東西。可是如果你覺得除了“學演算法、coding、A題的感覺很爽”或者說“我想晉級Final”之外,更期待某些其它的結果,那說明你真正應該搞的不是ACM。如果有一天,你並沒有因為搞過ACM而拿到一份很優秀的offer,或者申請時發現你拿的那些ACM獎完全沒有任何作用等等,你確信那時的自己仍然不會後悔參加ACM,我認為這才是真正適合去做ACM的心態。


 


找到“組織”


這裡的所謂“組織”,是指和你水平相近(最起碼討論的問題,層次不要差太多),並且願意經常和你交流的人,並不一定必須是一個團體。“組織”是相當重要的,相互交流是快速進步的一個重要因素,這個不僅限於初學者。當年我集訓隊在役的那段時光就是我進步最快的時候,因為我有兩個很強的隊友fishcanfly和mostleg,與他們兩個的交流讓我獲益良多,遠比之前一個人單幹的提高要有效率。


就現在ACM的發展狀況來看,想找到個組織應該不是很難的事情。能有在你身邊的人一起來做是最好的,像HIT的“ACM俱樂部”就是非常不錯的組織,很多學校的ACM隊也應該會有類似在集訓隊之外的“編外組織”一類,應該多去打聽打聽。如果實在不行,網上有很多的bbs,QQ群,甚至你在renren上多留意,都能找到很多的ACMer,交流應該不會成為一個主要的障礙。


如果實在是找不到組織,那就只能自己痛苦一點了,這點我也沒有什麼很好的辦法。不過這也並不代表就沒有希望了,我當年起步時HIT的狀況也差不多,我認識的很多大牛也都是從這樣的環境起來的。樂觀的來講,這種艱苦的條件是很能磨練人的,出了什麼問題都必須靠自己。對有熱情有毅力的人來說,是一個挖掘自己潛力的機會,並不見得是壞事。


 


要有毅力


這裡所說的毅力並不是指熬過肉體上的痛苦,比如說那個廣為流傳的“弱校ACM奮鬥史”中寫的,在基地打地鋪,每天泡麵+熬夜一類。當然我對這種精神是相當欽佩的,只是這些困難其實不算是什麼大問題,因為只要精神不累的話,肉體上的疲累並不像想象中的那麼可怕。


我覺得ACM很耗精力倒是真的。比如說你可能越學越發現要學的東西還有很多,似乎無窮無盡;或者你發現你周圍的人都進步神速,可是你自己卻還在龜速前進;又或者你在參加比賽時很多題都不會做,看完解題報告後發現竟然如此簡單,學會之後以為自己可以了,可是下次再比賽又有一大堆不會的題(我07年初做TC時就是如此)。大多數人總要遇到一個長期不斷被虐的過程,很多時候精神上會很痛苦,會冒出到底還要不要繼續做下去,做這些都是為了什麼之類的問題。實際上我05, 06, 07這三年每年都遇到過這樣的問題,現在看來,我很慶幸我堅持下來了。


事實上,我相信凡是真正喜歡ACM的人,是不會被這種困難擊敗的,只是應有一些心理準備,同時有一些決心才好。


 


不要迷信“神書”光環


其實這很簡單。很多神書確實神,可是不一定適合初學者。比如廣為流傳的,劉汝佳當年寫的那本黑書“演算法藝術與資訊學競賽”,也只是針對許久之前OI的那種“資訊流通性不強”的情況搞出的一個大雜燴,我當年剛開始搞ACM的時候就買了一本,結果擱了N年也沒看完。其實就今天的眼光來看,這書應該基本不符合時代了,要不然劉汝佳也不用大花心力再去編寫一套新的。還有眾口相傳的CLRS,雖然我不是拿它來入門,但是我隱約覺得,如果有個明白人在你身邊指點的話,這書倒是還不錯;如果是初學者自學,不見得會有很好的效果。


至於到底該選擇哪些資料來入門?我只能說因人而異。記得當時我大部分知識的入門方法就是在網上尋找各種資料,其實我覺得網上有很多資料講得非常通俗易懂,對於一個身旁無人指點的人來說,效果不見得會比那些神書要差。當然在這種“山寨式”的學過這些東西之後,還應該找幾本好書來仔細看一看,由於這時很多基礎問題不再是障礙,才能更加容易把握住這些好書中精華的部分。


 


多做難題


如果你去問那些牛人“這道題你是怎麼想到要用XXX方法的”,我估計大部分人都說不出個所以然來。其實很多情況下都是純憑直覺考慮到的數個思維方向,這種直覺是需要大量的練習來得到的,沒有那麼多“為什麼能想到”,類似於Roba口中的“條件反射題”一樣。所以要多做題。


不過這裡的“多”不是指數量多,而是質量多。所謂的難題也並不是指要做那種難到天頂的題,而是適合自己的難題。如果一道題能夠讓你經過數個小時甚至一天的冥思苦想,最後終於AC,我認為這樣的題才是最好的。當然這是你要有一些相關基礎的前提下才能做的,不要一上來就走極端。


事實上,我認為只有對思維進行這種接近極限的運轉,才能最大限度的加深對相關知識的理解能力,在眾多的idea中一一排除,最後找到正確的那條路,也能讓你每個方法的本質有一些更深的理解。而且這種方法過題,得到的成就感顯然不是刷十幾個水題能比得了的。


至於這樣的題該如何去找,看某些有難度分級的題單是一個不錯的方法,TC, CF這種題目分級相當明確的OJ也是不錯的選擇,或者乾脆去看一道題的AC數和AC率。這個可能需要做很久才能把握住哪些題適合自己,但是當有了一些基礎之後,至少要時刻提醒自己,多做有質量的題,少做水題。


 


不要做太多比賽


因為絕大多數的比賽都不是面向初學者的,所以我覺得初學者做比賽有害無益。就算是做比賽,也應該明白做比賽的目的是要警告自己還相當弱,激勵以後繼續努力,而不是要檢驗這段時間的學習成果一類。


由於剛入門的人知識方面還有相當多的空白,想提高是一件非常容易的事情,有大量的資源可供使用,自己線下練習完全足夠,我看不出比賽會有什麼特殊的神奇效果。在我看來,比賽主要鍛鍊和提高的是自己知識和技巧的運用能力,或者你可以看成是“招式”。比如我07年做了一年的TC之後總結了一下,發現我的知識水平似乎沒有顯著的提高,倒是思維的活躍度、臨場發揮能力有了顯著的提升,對實際上沒有超出自己知識水平的問題,AC率顯著上升。但是想達到這個效果,首先要有足夠的根底,然後才是去考慮該如何高效的運用你的內功。只靠比賽是沒辦法無中生有的。而且比賽連續失利很容易打擊一個人的熱情,這對初學者來說是很致命的。所以初學者對一般的比賽,建議還是少碰為妙。


 


附:我心中合格的隊伍應該具有的素質


如果你要問:什麼樣的隊伍是優秀的隊伍?當然,這個答案非常之簡單,三個全能型大神組成的隊伍就夠了。比如2011年IPSC的Petr + ACRush + tourist,你覺得這樣的隊伍還需要什麼別的嗎?


不過這個回答顯然沒有意義,這是任何隊伍所能達到的能力上界。所以我試圖從草根的角度出發,描述一下我心中一個“正常”的好隊伍(我預設上面的那種隊伍是不正常的)應該包含什麼樣的素質。當然並不是指下面這幾條都要滿足,而是這幾條是應該關注的比較重要的方面。


三人在ACM涉及到的各個大類都有很好的基礎。或者說,如果在比賽中遇到任何一類問題,且難度定位為“簡單”或者“中等偏低”,三人應該都可以獨立解決。我認為作為一個優秀的隊伍,三個發展全面的隊員是必不可少的。雖然不一定在各個方面都有解決難題的能力,但是基礎絕對不能差。
每個方向至少有2人可以對難題進行討論。如果一個方向只有一個人懂的話,可能這個人會有一些盲點,如果卡題了,也沒有人能夠與之討論。每個方向有兩個人深入的話,基本可以保證對絕大部分的情況都可以應付。
有一名知識面廣闊的隊員。這樣的人比較適合掌控全域性,可以對絕大多數問題的難度有準確的預估。
有一名編碼能力穩定的隊員。三人全都抽風的隊伍波動太大,作為一個優秀的隊伍,最起碼要保持一定程度的穩定,至少應該有一名隊員要有穩定輸出的能力。
有一名能夠“混”的隊員。這裡的混到底是什麼標準不太好解釋,從境界上比較類似於那句廣為流傳的名言“這道題我不會做,但是AC還是沒有問題的”。或者換句話說,一個隊伍應該有一個人有能力在關鍵時刻出“奇兵”,雖然並不一定要求有很高的成功率(否則就是神隊了),但是最起碼在最後關頭不至於毫無翻盤之力。
想一想,我06年在役的隊伍似乎在這五條上做得都還不錯,唯一的缺點是三人都還缺少歷練。也不知道是不是因為我對我們隊的配合相當滿意,所以影響了我對“好隊伍”標準的設定。總之,我認為上面那幾條是非常值得注意的幾個方面,或者說在組隊練習中應該注意的方向。


 


後話


其實上面這些東西可能只是我想說的一半左右,本來還想寫一些其他的條目,只是確實有些累了。要不是在renren上發過一個狀態讓外界給點壓力,我肯定就真的要半途而廢了。說到底,我還是對科普這種活動沒什麼興趣的。


當初做ACM的理由很簡單,我很喜歡那種經過多日苦思之後靈光一現,水到渠成的感覺;在看到那種將問題不斷抽象與擴充套件後,一個普適的框架竟也蘊含著如此神奇的定理,也能用那種神妙非常的方法去解決的時候,我會感到無比的興奮。對那些陶醉於數學與演算法,同時對國內本科教育極度不滿的人來說,ACM是一個很好的途徑,讓他們能夠自食其力,在自己喜愛的事物上盡情發揮自己的天分。


我懷念當初做ACM的日子,懷念與隊友共同奮鬥的時光,是因為那時的我,就像是牛頓那句名言中在海邊玩耍的孩子一樣,每天都能為自己撿到漂亮的貝殼而感到興奮。可能這也是我近幾年為什麼越來越不願再去做比賽的原因。當你不再滿足於ACM給你帶來的歡樂時,不妨跳出這個圈子,去外面看看。外面的世界很精彩,ACM只是一個開始,而絕不應該只是終點。


我祝願所有ACM初學者都能享受到ACM的魅力,也希望每一個初學者能通過ACM,找到屬於自己的廣闊天地。嗯。應該也沒什麼想要再說了,就這樣了。