Problem
將一個無向圖中,增加最少條邊,使得可以使用尤拉路徑或環道經過所有條邊。
Sample Input
|
|
Sample Output
|
|
Solution
同一個連通元件中,度數為奇數的點一定為偶數個,保留一組(兩個)奇數點,準備於其他連通元件串起,而其他的則兩兩相接(增加新的邊),保證每一個點一定能構成偶數度。
|
|
將一個無向圖中,增加最少條邊,使得可以使用尤拉路徑或環道經過所有條邊。
|
|
|
|
同一個連通元件中,度數為奇數的點一定為偶數個,保留一組(兩個)奇數點,準備於其他連通元件串起,而其他的則兩兩相接(增加新的邊),保證每一個點一定能構成偶數度。
|
|
將集合做交集、聯集、插入的操作,輸出每次操作的集合大小。
|
|
|
|
STL 高招解決,都有提供集合交集和聯集,但是為了方便查找,使用重新命名每一個集合為一個整數表示。
|
|
給一張無向圖,希望每一個點都剛好在 K 個不相交環上,如果不可能則輸出 -1,反之挑選最少花費的邊構成這一個條件。
|
|
|
|
一道明顯的最小費用流,每一條邊最高流量是 1,而對於每個點都通過 K 個不相交環 (沒有共同邊),則要將每個點拆分成出入兩點,也就是說總共會有 N K 個不相交的環,總流量會經過 N K 條邊。
|
|
給定一個凸包,詢問點是否在凸包內。
|
|
|
|
由於詢問次數相當多,必須將複雜度降到 O(log n)
,採用的方式將凸包其中一個點當作基準,則如果在凸包的點而言,一定會落在某個以基點拉出的三角形內部中,為了方便計算,則可以拿外積的正負邊界上。
得到可能的三角形後,從邊界中可以藉由外積計算是否同側。
採用射線法 O(n)
肯定是吃大虧的。
|
|
求任兩個相異質數總和介於 [L, R]
之間的個數。
|
|
|
|
一開始使用 O(n log n)
的二分解法,但是遲遲沒有通過,最後改用 O(n)
的方式遞減 index。
|
|
給每個節點的度 (degree),是否能構成二分圖?
|
|
|
|
劃分成兩個集合,則兩邊的 degree 總和一定會相同,因此得到了基礎的窮舉概念。
然後對於窮舉的時候,左集合的元素最大值一定要小於等於右集合大小,反之亦然。
// s 和 t 集合, max(s[i]) <= |t|
這樣窮舉只能保證基礎的條件,而事實上採用 greedy 的驗證方式,從最大度的點開始分配連線給最大度的點,如果最後能分配完成即可找到一種二分圖的解。當然,有人嘗試了 maxflow 的驗證方式也是相當靠譜,不過速度會慢了些,而且還不是很容易 coding。
而這樣的解法仍然會拉 TLE 的緊抱,因此考慮將相同 degree 的窮舉方式壓縮,例如說有 3 個 2 需要窮舉,而採用兩個集合劃分的方式 (0, 3) (1, 2) (2, 1) (3, 0) 四種方式 …,從 2^3 = 8 降到 4 次,速度會快快快很多。
|
|
接近 TLE 的版本,概率通過得 AC。
|
|
遞移性 a->b, b->c 則 a->c。
給定一張圖的遞移,求不改變任兩個點的遞移關係,最多可以有多少邊、最少需要多少條邊。
|
|
|
|
從最多條邊來說,最簡單使用 floyd 內閉包的算法 O(n^3)
。
|
|
最後計算 1(true) 的個數即可,但是這一題 n 最大為 1000,必須從 O(n^3) -> O(n^2)
,取而代之,採用 dfs 的方式,把每一個點 s 當作起點,則可以搜索到的點 t,都存有遞移關係 s->t。
而在處理最少條邊,採用強連通元件 (SCC),先將數個點縮成一個元件,則一個強連通元件內的個數只需要使用一個環即可代替原先的遞移關係。縮圖完之後,會產生 DAG 圖,DAG 圖上仍然會有多餘的遞移關係,從 a->b, b->c, a->c 中,可以發現 a->c 可以不存在。
最後,採用 bfs 的方式,對於每個點 s 當作起點找到最長路徑,假使 t 距離 s 大於 1,且存在 s->t,則可以再少一條邊。
|
|
找到一個完備集合,其任兩個數字做 AND 和 OR 運算都在集合中。
給定部分集合,請問至少還需要幾個元素使得其變成完備集合。
|
|
|
|
這一題從傳錯題目開始已經放著很久,當時怎麼樣都沒有想法,直接著手 O(n * 2^20)
最慘運行方式,其實這種複雜度與通過的複雜度就差那麼一點的 n。 // 肯定是死在 n。
其實可以發現到,假使挑選 i-th bit 很有可能會連帶其他的 bit 一同帶上,因此對於 i-th bit 最小化攜帶的 bit (做 AND 最小化)。
最後窮舉攜帶 i-th bit 是否要挑 (OR 所有攜帶的 bit),複雜度降至 O(2^20)
|
|
現在有 N 個積木,兩個人輪流拿 X 個積木 (X in Set, X <= 20),直到最後一個人拿走最後一塊積木獲勝,如果無法拿取則對方獲勝。
給定一個勝負的前 M 個積木的博弈結果,求 |Set| 最小為何,相同時則輸出字典順序最小的。
|
|
|
|
這一題很賊的地方在於 X <= 20,那麼已經可以發現可以窮舉集合情況,從最小的的集合順序開始窮舉。
窮舉的方式採用 stl 中的 next_permutation。
|
|
給定一個置換群,要我們表示成以下特定的形式,1 ≤ n ≤ 200000。
由右至左看,第一次為了填5必須移動2位,第二次移動填4也是移動2位
3 2 5 1 4 -> 1 4 3 2 5 移動 2
1 4 3 2 5 -> 3 2 1 4 5 移動 2
3 2 1 4 5 -> 2 1 3 4 5 移動 2
2 1 3 4 5 -> 1 2 3 4 5移動 1解題者:李育賢
解題日期:2008 年 3 月 21 日
|
|
|
|
李育賢他的解法使用線段樹,靜態操作 shift rotate 和 remove 的問題,仔細想想似乎也不難,但是沒想到我用了模擬的塊狀鏈表解決這一道題目。
為了解決 shift,還必須增加數字的映射,否則沒辦法再 O(sqrt(n))
時間內完成操作。
塊狀鏈表相當暴力模擬,最簡單地盡可能讓塊差不多是 sqrt(n) 個元素,這樣再 shift 的時候,可以將 head 指標移動次數卡在 sqrt(n) 將給一個操作都限制在 O(sqrt(n))。
塊狀鏈表看看就好,還是回去寫線段樹吧!
|
|