【BZOJ - 2144】跳跳棋
@跳跳棋@
- @跳跳棋@
- @題目描述@
- @分析1@
- @分析2@
- @代碼實現@
- @END~@
@題目描述@
Description
跳跳棋是在一條數軸上進行的。棋子只能擺在整點上。每個點不能擺超過一個棋子。我們用跳跳棋來做一個簡單的游戲:棋盤上有3顆棋子,分別在a,b,c這三個位置。我們要通過最少的跳動把他們的位置移動成x,y,z。(棋子是沒有區別的)跳動的規則很簡單,任意選一顆棋子,對一顆中軸棋子跳動。跳動后兩顆棋子距離不變。一次只允許跳過1顆棋子。
寫一個程序,首先判斷是否可以完成任務。如果可以,輸出最少需要的跳動次數。
Input
第一行包含三個整數,表示當前棋子的位置a b c。(互不相同)
第二行包含三個整數,表示目標位置x y z。(互不相同)
Output
如果無解,輸出一行NO。如果可以到達,第一行輸出YES,第二行輸出最少步數。
Sample Input
1 2 3
0 3 5
Sample Output
YES
2
【范圍】
100% 絕對值不超過10^9
@分析1@
這道題真的很跳……
首先這樣的題如果用絕對坐標(a, b, c)來做絕對不好做,所以考慮使用相對距離來表示點。對于三元組(a, b, c)將它表示為(l, r, m) = (b-a, c-b, m),含義為:(左邊點離中間點的距離,右邊點離中間點的距離,中間點坐標)。
然后對于題目所提到的操作將操作拆為兩種:邊緣點往中間跳,中間點往兩邊跳。
當r>l時,左邊點可以往中間跳,從(l, r, m)轉移到了(l, r-l, m+l)
當l>r時,右邊點可以往中間跳,從(l, r, m)轉移到了(l-r, r, m-r)
中間點往兩邊跳沒有附加條件,從(l, r, m)可以轉移到(l, r+l, m-l)與(l+r, r, m+r)
這樣就可以建圖,問題轉化為求圖上兩點最短距離。
但是……這還是不夠??紤]到中間往兩邊跳是兩邊往中間跳的逆操作,我們可以給邊定向,即只考慮兩邊往中間跳的操作。然后我們發現,對于某一個狀態(l, r, m),通過兩邊往中間跳的操作后,l和r不會變得更大,所以這是一個有向無環圖。更進一步地,當l < r或l > r時,狀態有唯一轉移,否則狀態無轉移。聯想到有根樹上除根節點外每個節點只有一個父親,根節點沒有父親。所以這其實是一顆樹,且狀態(l, r-l, m+l)或(l-r, r, m-r)是狀態(l, r, m)的父節點,當 l = r 時狀態(l, r, m)是根節點。
問題轉化為求樹上兩點最短距離。
再簡單轉化,就是求樹上兩點的LCA。
@分析2@
分析到這一步已經很不容易,但是還還還不夠……
考慮到我們一般做LCA的方法:倍增法。先 O(log2n) O ( l o g 2 n ) 的時間將兩個點跳到相同深度,再一級一級地同時往上跳直到兩個點相同。但是倍增法我們需要 O(n) O ( n ) 的dfs預處理,所以此處并不適用。
再觀察一下這個轉移的定義:
當r>l時,左邊點可以往中間跳,從(l, r, m)轉移到了(l, r-l, m+l)
當l>r時,右邊點可以往中間跳,從(l, r, m)轉移到了(l-r, r, m-r)
再聯想一下gcd的減法形式gcd(x, y) = gcd(y, x-y) = gcd(x-y, y) ( x > y )
是不是有點像?對于某一個狀態,假設 l < r,則(l, r-l, m+l),(l, r-2l, m+2l),…,(l, r%l, m+r/l*l)都是狀態(l, r, m)的祖先。但是!與gcd算法不同的是,如果r%l=0的話則不能跳到最上面的節點,因為在最后的時候 l 將會等于 r。
因為gcd的復雜度可以證明得到不超過 log(n) l o g ( n ) ,所以我們就有了一個代替倍增的玩意兒。
具體來說,我們先求出兩個點的深度,以及兩個點所在樹的根節點。比較根節點判斷是否有解。
【為了簡稱,我們稱(l, r, m)到達(l, r%l, m+r/l*l)為“大步跳”】【作者太Lazy了233】
然后,對于深度較大的節點,假如它通過“大步跳”到達的節點深度比另外一個節點大,則它就直接跳到深度相同的地方;否則就跳到“大步跳”到達的節點,并繼續迭代。
再然后,取兩個點“大步跳”到達的點中深度較大的點,假如說在這個點之前它們就已經相遇了,就直接跳到相遇的點作為它們兩個點的LCA;否則就同時往上跳到深度較大的點的深度,并繼續迭代。
@代碼實現@
非常丑陋……不建議參考。
如果還有什么不懂的地方就評論在下面吧,作者會盡力解疑的。
【這道題太毒瘤啦……建圖卡死人,LCA卡死人,竟然冒出來個gcd……】
@END~@
就是這樣,新的一天里,也請多多關照哦(ノω<。)ノ))☆.。~
總結
以上是生活随笔為你收集整理的【BZOJ - 2144】跳跳棋的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: it企业实习_大学生IT公司实习报告
- 下一篇: 如何对一个产品编写完整的用户故事?