這個部落格已經快一年沒有更新了……
翻看之前的題解和總結記錄,頓感記錄的快樂——回顧之前的知識,找回以前的記憶,理清頭緒,這正是備戰比賽時需要做的事。而擁有部落格這個平台,能輕鬆地應對這個任務。
是時候繼續更新了。把這快十天中做過的一些有趣的題目講講吧。
題目大意:給出乙個矩陣陣列 ( 1≤
n,m≤
500 ) 和乙個數
d 。點 (x
,y)上的數字為 h,它被稱為「d-山峰」當且僅當從這個點出發,在不經過上面的數小於等於 h-d 的格仔的前提下無法到達數字比它更大的格仔上。問「d-山峰」的個數。
這道題咋看上去像搜尋,其實不然。因為每個點能走到的格仔都是連成一片的(顯然),很容易想到可以先把當前點能走到的點全部標記為「可行」,如果與這個點連成一起的區域中最大的數超過了這個點上的數,這個點就不能計入答案。
這樣一來,問題變成了「如何將所有【數字超過某個數的格仔】標記為可行」以及「詢問連續一片可行點的數的最大值」。根據這個想法深入思考,不難發現:如果我們將所有的點按數字從大到小排序,那麼在遍歷排好序的點時,可行點的數量是不遞減的。
這就啟發我們使用並查集解決問題:遍歷這些點的時候我們把所有「需要標成可行」的點打上標記,也即與周圍可行的點並到一起,成為乙個個可行點集。由於點是排好序的,每次要標記的點必然是連續的一片,此時可以用個變數
p 標記上一次已經標記了前
p個點,這樣便不需要重複標記可行點,使得每個點只需要標記一次。在合併點集的時候順便維護點集的最大值,就可以 o(
1)判斷當前點了。總的時間複雜度為 o(
nm) 。
題目大意:給定乙個正整數 n ( 1≤
n≤700000
),當正整數對 (x
,y) 滿足 1x
+1y=
1n! 時稱其符合條件。問符合條件的正整數對的個數。
拿到這道題目,感覺就是分析條件中的那個等式,從中找出符合條件的
x 與
y的規律。可惜數學功底差,寫到一半無論如何都寫不下去了。
其實方法很簡單。顯然有x+
yxy=
1n!
那麼可以得出:x+
y=a
xy=n
!⋅a
如果令 y=
a−x ,就有x(
a−x)
=n!⋅
a⟹a=
x2x−
n!顯然
a 一定為正整數,也就是說
x>n!
。如果再令 x=
n!+k
,就有a=
(n!)
2+2k
n!+k
2k=(
n!)2
k+2n
!+k
此時如果
a 要是整數,就意味著 k是
(n!)
2 的因子。那麼 (n
!)2 的因子個數就是我們需要的答案了。
答案很大,需要使用高精度壓位,但是這仍不足以在時限內通過此題。
注意到在進行高精度乘法的時候,每次乘的都是乙個較小的數,可以先用另乙個變數儲存目前乘過的數的積,等到這個積比較大時答案再把它累乘上去,同時重置這個變數。這種做法能有效節省進行高精度乘法的次數,顯著降低時間複雜度。
題目大意:給出 n 個正整數 ( 1≤
n≤30000
),任意兩個正整數可以合併成乙個正整數,合併後的數值以及代價皆為兩數之和。問將所有的數合併成乙個數所需要的最小代價。
萬惡的合併果子。
這天的題目裡面有5道題,其中4道題竟然全都是「合併果子」類題目。而解決這4道題的關鍵,就是先解決原版題目《合併果子》。
悲劇的是,我在看這道題的時候,誤以為是只有相鄰的果子堆才能合併。於是先想到了區間dp,然後不斷地改進、改進……比賽結束之後驚喜地發現只有10分,一問同學……
這是我從今年7月份訓練以來的第一次大失利,排名掉到了比賽總人數的一半以後。看錯題這種低階失誤,我已經很少犯了。以後一定要杜絕這種低階失誤(丟了400分那種酸爽)。
題目大意:給出乙個有障礙的矩陣圖 ( 1≤
n,m≤
200 ) 以及乙個物體的初始位置。總時間 t ( 1≤
t≤40000
) 被分成了 k 段 ( 1≤
k≤200 ),單個時間段內該物體只會向某個固定方向移動。每個時刻你可以選擇物體向當前時刻所定的方向移動,抑或停止不動。問該物體在總時間後最多移動了多少格。
比較典型的類搜尋題。一年前做過一道此題的弱化版本(傳送門),依稀記得當時只用個寬搜就過掉了,但是面對資料較強的此題,搜尋無能為力。考試時儘管努力去想這道題更高階的解法,但沒有想到較好的優化,於是作罷。
正解是dp。定義 f[
i][j
][k]
表示當前走到的位置為 (i
,j) 且已走完前
k 段時間後能移動的最大格仔數。顯然樸素做法是 o(
2004
)的。但是因為在單個時間段裡有固定的方向,針對這個方向我們就可以使用單調佇列優化。
舉個例子:當前時間段向下移動時有 f[
i][j
][k]
=f[i
−x][
j][k
−1]+
x 那麼固定 j,i 遞增,單調佇列中存放 f[
x][j
][k]
−x,(
1≤x≤
i−1)
,取隊頭為當前的最終決策,並維持單調佇列遞減(為什麼?)。
對於其他的方向只需要照葫蘆畫瓢就可以了。
題目大意:乙隻青蛙從第 n 片荷葉開始,在 n 片連續的荷葉上跳躍 ( 1≤
n≤20000
)。如果它在第 i 片荷葉上,那麼它會選擇 1~i 中的一片荷葉跳過去。問跳到第 1 片荷葉上的期望跳躍次數。
應該說我對概率題最傷腦筋了,完全不會做(因為連基礎的概率知識也沒有掌握),考試時碰到這道題,直接棄療。
其實應該這麼想:如果設 f[
i]為從第 i 片荷葉開始跳的期望跳躍次數,那麼就有:f[
i]=(
∑i−1
j=1f
[j]+
1)+f
[i]i
即f[i]=∑
i−1j
=1f[
j]i−
1+1
時間複雜度可以做到 o(
n)。 看完題解突然覺得自己很弱渣……這麼簡單的東西怎麼我就想不到?
幾道智力趣題
網上找了幾道智力題做了做,記錄乙個參 附在後面。1.有兩根不均勻分布的香,香燒完的時間是乙個小時,你能用什麼方法來確定一段15分鐘的時間?2.有兩位盲人,他們都各自買了兩對黑襪和兩對白襪,八對襪子的布質 大小完全相同,而每對襪子都有一張商標紙連著。兩位盲人不小心將八對襪子混在一起。他們每人怎樣才能取...
演算法趣題(二)
問題 有一組寫著數字 1 11 100 10010 0 的紙牌,按照從小到大的順序排列著。最開始所有的紙牌都背面朝上。接下來按照規則翻牌 第一次從第 2 22 張紙牌開始,隔一張牌翻牌,於是第 2 4 6 8 100 2 4 6 8 100 2 4 6 8 10 0 位置的牌會變成正面朝上 第二次從...
php趣題小記
題目一 a abc a echo a abd題目二 function myfun a a 10 echo myfun a myfun a 20myfun 10 雙引號只解析變數不解析函式 得到myfun 10 然後先執行函式myfun 10 得到20 最後輸出 20myfun 10 題目三 var ...