第九屆藍橋杯國賽參賽心得
ps:這是我第一次參加藍橋杯的國賽,非專門玩ACM的,也很少去徹底鑽研很高深的演算法
我參加的是C/C++大學B組,客觀來說題目從題難度不高,總共6道,我估計自己做出了4.5道,最後拿的是國二,沒有一等獎有點遺憾,不過歸根結底還是自己水平還不夠吧。簡單說下國賽的題目內容吧。
第一題簽到題,大概意思是用面額為1,2,5的鈔票換取200的金額,並且有約束條件“面額為2的張數恰好為1的10倍”,三種鈔票必須有(任何一種數量不得為0),問兌換最少的鈔票數量是多少。這其實是一道數學問題,即使不借助程式設計或其他工具也能用數學知識求解,而且我求出的解也只有一個,那肯定就是答案了,沒啥特別高深的技巧。
第二題講的是有n盞燈,任意相鄰的兩盞燈不得同時開啟,問n盞燈的亮法有多少種組合。這題我觀察了一下就找到了規律,n=2有3種,00(相鄰可以同時滅,但不能同時亮),01,10,n=3有5種,000,001,010,100,101,n=4有8種,一直下去其實是一個斐波那契數列。或者也可以用DP的思想推出這個規律,當第n盞亮時,n-1一定不能量,那麼有兩盞燈的情況已經確定了,此時f(n) = f(n-2)。當第n棧燈不亮時,有f(n) = f(n-1),兩種情況加起來就是f(n) = f(n-1) + f(n-2)了,顯然這就是斐波那契數列的遞推公式。
第三題程式碼填空題,填的是格雷碼生成的演算法,然後最核心的一句就是“找到格雷碼最右邊的1,並對其左邊的1位取反”。也就是找1001
第四題是最簡單的一道程式設計題了,簡單來說就是給定n和k,對於任意x(0 <= x < n),能夠不斷+1或+k,使得結果為最接近的一個n的整數倍,當然x為0時就不用做任何操作了,為x最壞的情況下最多多少步操作就可以達到目的。這道題DP一下應該沒問題,對於n-k<x<n,當然是只可以+1,因為+k肯定超過n了,對於0<x<n-k,可以+1或+k,即f(x) =min{ f(x-1), f(x-k)} +1,遞推公式很明顯了。
第五道題我沒做出來,雖然我有思路,感覺是用DP,但是後面測試資料總是不對,應該是我自己沒能找出程式碼上的問題。
第六題是求矩陣元素的總和,第i行j列的元素是gcd(i, j)的平方,我用了還是比較暴力的計算總和,應該只能過30%的資料,因為後面矩陣很大。我認為這個矩陣每一列的總和都有一個規律(或者說一個公式)能夠簡便計算出來,但我想了很久沒找到。第一行和第一列的元素必定為1,因為1和任何數的最大公倍數必定為1,對角線上的元素必定是1,4,9,16….因為同一個數的最大公倍數就是其本身了,而且這是一個對稱方陣,只需要計算對角線一邊的三角形的元素再*2就可以了,我想每一列總和可能還會有規律,不用對每一個位置都算最小公倍數,但是我想了很久沒找出來,也可能是我一開始的出發點就不對吧…
總結
1、對於演算法來說數學永遠是不可缺少的一部分,尤其是找規律和數論這一塊,ACM其實也非常喜歡考這一方面,我數論這塊比較弱,畢竟我們沒有專門開數論的課程,只是在密碼學這門課上大概瞭解了一些概念。
2、不要小看斐波那契數列,有許多題目喜歡考的,但是很多時候它的規律不容易被看出來,畢竟容易看出來是斐波那契就太沒意思了,我之前刷過一些程式設計題遇到有四五道都和斐波那契數列有關的
3、這次比賽用到了DP(動態規劃),DP是我認為五大經典演算法中最難掌握的了,不是因為它理解起來有多難,而是關於DP的問題變化多種多樣,例如最經典的01揹包求最優解,又例如第二題求所有組合情況的數量,還有很多很多
4、要真正學好演算法還是需要蠻多投入的,就像學數學一樣,演算法不是說看下書理解下概念就能學會的,理解之後還要練,說白了就是刷題,不刷題永遠不知道你學過的演算法能用在哪些地方
5、第三題的格雷碼程式填空我覺得出的挺有意思的,因為它的思路回到了計算機最基礎的部分——補碼
其他
第一次參加國賽,第一次出廣東省,第一次到北京,除了比賽還去參觀了一些景點什麼的,去天安門和故宮轉了一圈,進去清華大學感受了一下里面的氣息,倒數第二天花了一下午逛頤和園,在佛香閣上見到了非常不錯的景色,天壇去的有點晚,祈年殿已經關門了有點可惜,晚上去了鳥巢和水立方。就是在北京消費對我這個長期在二線城市生活的人來說有點高,尤其是二環那一帶...