我的做題筆記 (轉)
UVA 100 - The 3n + 1 problem - 0:05.107 316K
TLE 4次 WA 1次 AC n次
看了OIBH的介紹,我當初是決定用模擬+記憶化的方法來做,不過連續2次TLE了。後來改用了直接模擬不記憶的方法,結果還是TLE,真是百思不得其解。Bamboo說我應該得WA的,因為會有i>j的情況。我想想是該考慮上這種情況,又寫了。這下子好了,不是TLE而是WA了,原來是輸出的時候把後的i和j輸出了,我這才知道為什麼Bamboo的程式要先輸出i和j再做交換。真笨!!
錯誤總結:
之前的TLE,估計是因為沒有考慮細密,忽略了i>j的情況。WA是因為輸出的時候也沒有考慮好。如果用上記憶化,可能速度會快上一點。
UVA 101 - The Blocks Problem 0:00.040 64K
TLE 2次 PE 1次 AC 2次
這次錯在沒有好好讀題目,沒有處理好輸入不合法的情況,結果陷入死迴圈導致TLE(我發現UVA的TLE似乎都是死迴圈或是沒考慮周密情況而發生的)。
PE是受了樣例輸出的HTML的誤導。程式寫得非常複雜,第一次的程式(101.pas)有3K,不過思路是可以看得很清楚的。第二次(101_2.pas)修改到2K後,思路有點看不清了,但核心就是把各段程式碼中重複的部分合起來,多次的同形式內容寫成過程()
錯誤總結:
沒有認真讀題。
UVA 102 - Ecological Bin Packing - 0:00.555 316K
AC 1次
1次AC,挺高興的。不過這道題目也沒有什麼難度。技巧方面有幾個:
1.給定的資料讀入時是按B G C的順序,但是要求輸出的時候,序列應按字母順序排序,為了避免排序,在列舉的時候,就按B C G的順序進行。所以資料讀入部分,將讀入的資料以B C G的順序存放。
2.計算需要的移動數目時,不是一個個加,而是用總數減。如果箱子A專門放顏色X,則這個箱子中的顏色X肯定不用移動,其它的兩種顏色就要移動到別的箱子中去。靠這個,我們列舉i,j,k,表示三個箱子分別留下哪種顏色不移動(即對應了這個箱子的顏色),然後計算差值,即可簡單算出需要移動的數目。
3.由於i,j,k和肯定是6,k便可以不用列舉,而是用k:=6-i-j來計算。
4.為了方便記錄i,j,k,用一個陣列來儲存,這樣就可以整陣列賦值。
最後是老想昏頭的問題:能不能不改輸入的B G C順序,而是在列舉和計算的地方下手?我想是不行的,如果不把兩者統一起來,在計算的時候就會混亂。
UVA 103 - Stacking Boxes - 0:00.008 64K
WA 15次 OLE 3 次 AC n次
絕對是一個教訓!這是一道DP題,方法我已經有了,是starfish告訴我的。然而我幾乎是抄他的程式,結果卻是WA。我檢查了半天,懷疑了所有的部分,都沒有查出為什麼。最後重寫了一遍,竟然就OK了!複查的時候,我把程式段分別替換,竟然都還是WA!最後!!!!!我才發現竟然是宣告部分寫錯了,導致陣列越界!而UVA的給出的卻是WA!害死我了!!!!!!
錯誤總結:
檢查的時候不要漏檢查宣告部分,要在程式中用編譯開關開啟陣列邊界檢查!
URAL 1000 - A+B Problem - 0.02 sec 389K
?id=1000">
AC 1次
無話可說!
URAL 1005 - Stone pile - 0.07 sec 504K
AC 1次
這道題有兩種作法。
1.回溯法
由於N比較少(N<20),我們可以設有兩堆石塊A,B。每個石塊有兩種狀態:放在A,放在B。只要回溯列舉,算出A與B的差的絕對值,記下最小的就可以了。
2.DP
我們也可以設f[n,k]表示用前n個數是否可以算出k。我們可以得出狀態轉移方程:
f[n,k] = f[n-1,k-Wn] OR f[n-1,Wn-k] OR f[n-1,k+Wn]
這樣, 我們用兩個陣列進行翻滾就可以了
URAL 1009 - K-based numbers. - 0.02 sec 393K
AC 1次
這道題也有兩種作法.
1.列舉法
由題目條件2 <= K <= 10; 2 <= N; 4 <= N+K <= 18,我們可以推算出N<=8,數量並不算大,只要生列舉也是可以的。
2.遞推法
由於題目只要求計數,我們便考慮是否可以採用遞推、DP、組合數學的方法來計算。
我們可以這麼考慮:
假設f[n,1]表示的是首位為0的“合法”的n位K進位制數的個數,f[n,2]表示的是首位不為0的合法的n位K進位制數。
這樣,我們可以馬上得到邊界條件:
f[1,1] = 1 (一個0就是一個數)
f[1,2] = K-1 (K進位制是從0..K-1共K個數,除去0,就只有K-1個了)
我們每次在最左邊加上一個數字,然後我們可以寫出下列的遞推公式:
f[n,1] = f[n-1,2] (由於不能同時出現兩個0,所以在首位不為0的數前面加上一個0,就是這一類數的個數)
f[n,2] = f[n-1,1]*(K-1) + f[n-1,2]*(K-1) (在首位為0的數前面加上一個不為0的數字,在首位不為0的數前面再加上一個不為0的數字,就是這一類數的個數)
現在已經解決了這個問題,時間複雜度為O(N),空間複雜度為O(2N)。
不過還有的餘地。我們經過觀察,發現由第一個遞推關係,我們又可得f[n-1,1]=f[n-2,2],所以第二個遞推關係可以寫成:
f[n,2] = f[n-2,2]*(K-1) + f[n-1,2]*(K-1)
這樣我們就可以省去一個維,寫成:
f[n] = f[n-2]*(K-1) + f[n-1]*(K-1)
邊界條件也要隨之改變:f[1,1] = f[0,2] = 1
總之,邊界條件就是
f[0] = 1
f[1] = K-1
注意:如果我們直接從定義去理解,f[0]是想不出來的,這就是遞推的一個特點,要用公式去變換來找到具體值。
這樣,我們就把空間複雜度降為了O(N)。不過還能進一步再最佳化。我們發現f[n]只與f[n-2]和f[n-1]有關,也就是說,我們只需要儲存三個值就足夠了。
我們可以用f0,f1,f2來儲存,然後手工賦值翻滾,不過這樣太麻煩了。我們還有更好的辦法來實現:用MOD,寫成這樣:
f[n MOD 3] = f[(n-1) MOD 3]*(K-1) + f[(n-2) MOD 3]*(K-1)
這樣,我們只用定義一個陣列,翻滾的操作就不需要我們來手工完成了。空間複雜度也降為了O(1)。
另外兩道題URAL 1012和URAL 1013和這道題完全一樣,只是資料變大了,只能使用遞推來做,而且必須使用高精度計算。
URAL 1014 - The Product of Digits - 0.03 sec 393K - 2002.12.14
WA 2次 AC 1次
這道題也比較簡單,考的是你思維的嚴密程度。先來分析演算法:
題目給出一個數N,要求出一個數Q,其各位數字的乘積正好等於N。如果把N寫成N=a1*a2*a3*...*an(a1>=a2>=a3>=...>=an),則Q=a1a2a3...an。又可得知,0<=ai<=9(i=1,2,3,...,n),進一步,ai=0,1都不能取(取0乘積是0,取1乘了也白乘),所以2<=ai<=9(i=1,2,3,...,n)。我們就可以得出演算法了:將N分解為幾個2~9的因數的乘積,統計個數,從從大到小輸出相應個數的因數,就是所要求的數Q。顯然,分解的順序應是從大到小,這樣分解出的因數個數是最少的,數Q的長度是最短的,數Q才是最小的。如果N不能被完全分解,即分解完成後N<>1,則說明不存在這樣的數Q,就輸出-1。
好了,演算法是很簡單的,但是……題目有以下兩個陷井:
1.當N=1的時候,按我們的演算法,會沒有輸出,這時應特別處理,直接輸出1。我在做的時候,把N<10的情況都一起處理為直接輸出N。
2.當N=0的時候,如果不注意,你會認為應該輸出0。不過注意看題目:find the minimal positive integer,要求數Q為正數!所以應該輸出的是10!
最後該說吐血的事了:我WA了兩次都不是因為踏中上面的這兩個陷井,而是被HTML的編碼所害!如果用簡體中文來看這道題,不存在合條件的數時應該輸出的是"?",事實上!用ISO來看的時候,會發現那個"?"其實是"-1"!吐血吧?和UVA 103一樣,又是一個教訓!
錯誤總結:
看題目的時候,一定要把編碼切換成ISO。
-----------------------------------------------------
附:我以後做新的題目,就直接修改這個,而不再另開新文章了:)
2002.12.14 - 今天改了一下URAL 1009,加了最後一行:)還有做了URAL 1014。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-977250/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 字串做題筆記字串筆記
- 做題筆記 IIII筆記
- 考前做題筆記筆記
- 構造做題筆記筆記
- 貪心 做題筆記筆記
- P4139 做題筆記筆記
- 我的Hook學習筆記 (轉)Hook筆記
- 我的COM學習筆記 (轉)筆記
- [做題筆記] 資料結構筆記資料結構
- P4082 做題筆記筆記
- P7078 做題筆記筆記
- P1941 做題筆記筆記
- P1162做題筆記筆記
- CF1672F 做題筆記筆記
- 2024.10 做題筆記筆記
- 洛谷P1957 做題筆記筆記
- Ynoi 做題筆記(2024 年暑假)筆記
- 我的Webpack 筆記Web筆記
- 我的線上筆記筆記
- 我的Git筆記Git筆記
- 「分數規劃」學習筆記及做題記錄筆記
- 我的工作筆記(草稿)筆記
- 學會做筆記筆記
- 做題筆記——網路流與線性規劃24題筆記
- 閱讀部落格--《我們應當怎樣做需求分析?》筆記記錄筆記
- 我的Dll(動態連結庫)學習筆記 (轉)筆記
- 做題隨記
- 做題記錄
- 我的部落格搭建筆記筆記
- 我的前端筆記 之 JavaScript前端筆記JavaScript
- 我的爬蟲筆記(1)爬蟲筆記
- 推式子的做題記錄
- 學習sed & awk時做的筆記筆記
- DS做題記錄
- 我的前端筆記 之 flex 篇前端筆記Flex
- 我的前端筆記 之 bug篇前端筆記
- 我的前端筆記之git篇前端筆記Git
- 我的前端筆記之 meta 篇前端筆記