20150801 20150808 趣題詳解

2021-07-04 19:42:41 字數 3313 閱讀 4378

這個部落格已經快一年沒有更新了……

翻看之前的題解和總結記錄,頓感記錄的快樂——回顧之前的知識,找回以前的記憶,理清頭緒,這正是備戰比賽時需要做的事。而擁有部落格這個平台,能輕鬆地應對這個任務。

是時候繼續更新了。把這快十天中做過的一些有趣的題目講講吧。

題目大意:給出乙個矩陣陣列 ( 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 ...