標籤:style 資料 ar 代碼 時間 log 演算法 管理
第一題:
津津的零花錢一直都是自己管理。每個月的月初媽媽給津津300元錢,津津會預算這個月的花銷,並且總能做到實際花銷和預算的相同。
為了讓津津學習如何儲蓄,媽媽提出,津津可以隨時把整百的錢存在她那裡,到了年末她會加上20%還給津津。因此津津制定了一個儲蓄計劃:每個月的月初,在得到媽媽給的零花錢後,如果她預計到這個月的月末手中還會有多於100元或恰好100元,她就會把整百的錢存在媽媽那裡,剩餘的錢留在自己手中。
例如11月初津津手中還有83元,媽媽給了津津300元。津津預計11月的花銷是180元,那麼她就會在媽媽那裡存200元,自己留下183元。到了11月月末,津津手中會剩下3元錢。
津津發現這個儲蓄計劃的主要風險是,存在媽媽那裡的錢在年末之前不能取出。有可能在某個月的月初,津津手中的錢加上這個月媽媽給的錢,不夠這個月的原定預算。如果出現這種情況,津津將不得不在這個月省吃儉用,壓縮預算。
現在請你根據2004年1月到12月每個月津津的預算,判斷會不會出現這種情況。如果不會,計算到2004年年末,媽媽將津津平常存的錢加上20%還給津津之後,津津手中會有多少錢。
解題過程:
送分題,類比即可,但是要注意最後結算的時候除了存的錢,別忘記加上12個月累積下來沒有花掉的錢;
15分鐘左右一次AC;
第二題:
題目大意:給出n堆果子和各自的重量,要兩兩合并成一堆,合并的代價是兩堆的重量和,求最小的總合并代價。
解題過程:
老題目,每次選取最小的兩堆合并,直接迴圈找O(n^2)必定是逾時的,因此可以用小根堆最佳化,但是手寫堆有些麻煩。在建蘭培訓時提到過一種 更好的方法:
開兩個隊列,初始隊列1為所有堆的重量,合并後的重量放到隊列2裡,每次取出兩個隊列隊首小的那個的,重複一次,將兩個值合并放到隊列2裡。
第三題:
題目大意:
讓一個隊伍儘可能少的人出隊,使隊伍排成以某個同學為最高,向左右遞減。
解題過程:
直接分別從左至右,從右至左求以第i個人為結尾的最長上升子序列,在枚舉i取最大值即可。時間複雜度O(n^2+n),或者用另外一種方法二分最佳化到(Onlogn+n);
第四題:(較難)
題目大意:給出N位的豎式加法,每一位都用字母表示,求出字母代表的數字;(輸入資料保證唯一解)
解題過程:
一看便是搜尋題,但n最大有26,直接枚舉字母代表的數字要O(n!)的時間,要加適當的剪枝。
基本演算法是回溯,記錄字母代表的數字,和每個數字是否用過,從右往左處理每一列,如果碰到字母未確定,就枚舉+dfs,並記錄進位的情況,如果同一列有2個字母已經確定,那麼可以直接計算另外一個,有衝突的話就回溯;
不加任何剪枝能過9個點,50分鐘左右寫完。
剪枝:由於題目資料保證只有唯一解,用一個flag記錄是否已經找到答案,flag=1的時候就直接return;能過10個點。
最佳化1:枚舉不確定的字母的值得時候,改為從n-1到0(原來是從0到n-1),這樣效率要快得多,能過11個點,第12個點1100ms左右,就差一些。
然後就卡了N久,百度了半天感覺所有剪枝都用過了,結果卡在了1029ms,就是過不去。。。
最後抱著僥倖心理把string 改成了char數組,一提交居然600ms+AC了。難道取出char數組中的一個元素要比取出string中的一個元素快得多?百度了一下,可惜都沒有說這個。八成是這樣了。
被最後一個點噁心了2個小時。正道題估計3個小時才AC。
收穫:
訓練了耐心。。第一次寫出5000B+的代碼。。
DFS時迴圈變數從小到大改為從大到小可能會大大加速程式已耗用時間。