Problem
給予每一個格子的得分,分數為鄰近九格的 L 個數 (1 個 1 分) 加上自己是否為 L (3 分),因此最低 0 分,最高 12 分。
保證只有唯一解。
Sample Input
|
|
Sample Output
|
|
Solution
不斷地刷新已知的可能結果,慢慢從邊緣開始向內侵蝕已知解。
要做整數線性規劃看來是不可能,用刷新的方式看看是否可以噴出解。
|
|
給予每一個格子的得分,分數為鄰近九格的 L 個數 (1 個 1 分) 加上自己是否為 L (3 分),因此最低 0 分,最高 12 分。
保證只有唯一解。
|
|
|
|
不斷地刷新已知的可能結果,慢慢從邊緣開始向內侵蝕已知解。
要做整數線性規劃看來是不可能,用刷新的方式看看是否可以噴出解。
|
|
計算 base B 下,每一個 digit 都是 d 的情況,長度為 N,mod M 的結果為何?
|
|
|
|
找到
$$d B^{0} + d B^{1} + ... + d B^{N-1} \text{ mod } M \\ \Rightarrow d \frac{B - 1}{B^{N} - 1} \text{ mod } M$$由於 M 超過 int,運算起來仍有機會 overflow,因此要使用模乘法,也就是相當於直式乘法的運算,防止 (a*b) mod M 溢位。
|
|
給一個整數 N,接著詢問 x,有多少 gcd(i, N) <= x
。
|
|
|
|
先把 N 的因數 f 全部找出,原則上不超過 2000 個,然後建出 phi(N/f[i])
。
當要知道 gcd(i, N) = x
時,相當於找到 gcd(i/x, N/x) = 1
,任何與 N/x
互質的個數。建造完後,對於每次詢問二分答案即可。
很多地方忘記用 long long,吃了不少 Runtime error。
|
|
給予梯形兩點座標、四個邊長。找到另外兩點座標。
|
|
|
|
向量旋轉找解。
|
|
在現有的鋪設下,還有幾處建築物之間沒有連通。
找到花費最小的歐基里德距離生成樹
|
|
|
|
直接用 kruskal 就可以完成,但是建造邊最慘將會達到 O(n^2)
,因此效率並不好,好幾年之後回過頭來寫這一題。
對於 EMST 可以使用 Delaunay triangulation 完成。Delaunay triangulation 原則上可以在 O(n log n)
時間內完成。由於 EMST 是 Delaunay 的 subgraph,而 Delaunay 保證 edge 數最多為 3n - 6
。套用 kruskal 的 O(E log E)
算法就能保證在 O(n log n)
時間內完成。
Delaunay triangulation 目前實作有 D&C 和 random 兩種。
計算幾何資料請參照 morris821028/Computational-Geometry 下載。
廣泛的比較下,兩者期望都在 O(n log n)
完成,而實際結果 D&C 普遍速度快很多。random 作法很吃機率期望,原因是要支持動態的 point location 操作,沒有一個好的資料結構來保證每一步的搜索效率,教科書上給予一個類似可持久化結構的 DG structure,深度是期望的 O(log n)
,實作起來只會比 O(n)
快個常數倍。但 random increase algorithm 對於演算法的證明的確是比較容易,而且步驟相當好說明。
當效率不好去學 D&C algorithm,一開始要對座標進行排序,也就是不支持動態 (離線操作),接著針對 x 座標剖半,兩個完成 Delaunay triangulation 的凸包進行合併,接著需要將中間縫隙穿針引線地縫起來。因此要找到兩個凸包的下公切線,然後開始攀爬上去,保證一開始的下公切線一定是 Delaunay edge,然後開始窮舉下一個 Delaunay edge,過程中也不斷地移除不適的邊。
有相當不錯的資料結構可以快速地搜索公切線、圍繞凸包的頂點 … 等,但是根據教科書給予的計算,每一個點的 degree 期望值不超過 9,意即偷偷地窮舉攀爬不影響效率。
關於三點共圓,詢問一點是否在圓內的操作,投影到拋物面上,三點在投影結果上拉出一個平面,若點在圓內,則保證該點在平面的下方。求出外心計算,會造成誤差 (無法儲存除法運算結果),換成拋物面的思路魯棒性高。
下附 D&C algorithm 的做法,關於 random 就放在 github repo 封存了。
|
|
給一棵樹,接著有數次操作將路徑 (u, v) 上的所有節點權重加上 k。
請問最後每一個點帶有的權重為何?
|
|
|
|
參照 zerojudge b322. 樹形鎖頭 的解法。
A[]
: 子樹總和B[]
: 節點權重增加路徑 u 到 v 的權重為 k 時,路徑相當於 u 到某點 x 再到 LCA(u, v) 接著 y 最後 v。
那我們增加節點 u, v 的權重
B[u] += k, B[v] += k
,減少其 LCA 的權重B[LCA(u, v)] -= 2k
,然後你會觀察A[]
的部分,權重增加 k 的只會有 u-v 之間的所有節點。
|
|
平面上有 N 個點,並且給定數條有向邊,在這個遊戲中,必須從某個點出發,沿著邊回到起點。每一條邊最多經過一次,而點可以重複走。
每經過一條邊,可以獲益每單位長 X 的利益,但是使用一條邊的成本為 Y。
請問最大獲益為何?
|
|
|
|
目標將每一個點調整 indeg = outdeg
,要將多餘的邊捨去,只要滿足 indeg = outdeg
,則可以表示平面上有數個尤拉環道。
接著建造最少費用流的模型,來捨去掉多餘的邊。當存有邊 e(i->j)
時,outdeg[i]++, indeg[j]++
,一開始選擇所有 cost(e(i->j)) > 0
的邊,作為初始盤面,對於 cost(e(i->j)) < 0
先不選,選擇獲益為負的結果並不好。
如果 cost(e(i->j)) > 0
,建造邊 i->j, flow: 1, cost: cost(e(i->j))
,假使在最少費用流中選擇這一條邊時,就會將 deg 數量減少。對於 cost(e(i->j)) < 0
一開始並沒有在盤面上,如果流經這一條邊,則說明將會增加這一條邊。
|
|
組合的反函數,現在給定組合數,輸出是由哪幾種組合可以配出組合數。
|
|
|
|
先預見表,完成前幾項的結果。
看著巴斯卡三角形單純看 i,對於 C(n, i)
是一個嚴格遞增的函數。因此窮舉 i,針對組合數進行二分搜索。
為防止越界,在整數計算上可以利用除法進行比大小。
|
|
金融交易,它們希望賣出、買進交易結束後的差為零。
意即將數字分兩堆的結果相同。
|
|
|
|
由於保證 0 < a[i] <= i
,基於這一點,可以發現到只考慮一個數字 a[1]
時,必然可以湊出 1 - a[1]
,當考慮第 i 大數字時,保證前 i - 1 個數字可以湊出 1 ~ (i-1)
,加上第 i 個數字必然可以湊出 1 ~ (i-1)+a[i]
(1, 2, 3, ..., i-1, a[i], 1+a[i], ..., i-1+a[i]
)。
而事實上,可以湊出所有的 1 ~ sum[i]
,根據遞歸是可以證明的。只要總和是偶數,必然可以劃分成總和相同的兩堆。排序一下,從大的數字開始挑,貪心去完成目標的總和。
|
|
在一個二維平面中,灑落 N 個垃圾,機器人從原點 (0, 0) 依序要蒐集垃圾,機器人一次承載 W 重量的垃圾,隨時可以返回原點將垃圾放下。
請問依序收集垃圾的最少花費為何?
|
|
|
|
一開始得到方程式 dp[i] = min(dp[j-1] + cost[j, i] + dist[j] + dist[i])
必須滿足 w[j, i] <= C
,其中 j <= i。
其中 dp[i]
表示依序收集前 i 個垃圾的最小花費,cost[j, i]
表示走訪編號 j 到 i 垃圾位置的花費,補上原點到編號 j,並且收集完從 i 回到原點。
這樣的方程式轉換需要 N^2
時間,化簡一下式子
|
|
會發現 i, j 獨立,也滿足垃圾重量累計遞增,因此盡可能保留 dp[j-1] - cost[j] + dist[j]
小的結果,並且重量不超過限制,當重量超過限制時,該組答案在隨後保證再也不會用到,直接捨棄之。
核心就是單調隊列的思路。
|
|