跳跳棋是在一條數軸上進行的。棋子只能擺在整點上。每個點不能擺超過乙個棋子。
我們用跳跳棋來做乙個簡單的遊戲:棋盤上有3顆棋子,分別在a,b,c這三個位置。我們要通過最少的跳動把他們的位置移動成x,y,z。(棋子是沒有區別的)
跳動的規則很簡單,任意選一顆棋子,對一顆中軸棋子跳動。跳動後兩顆棋子距離不變。一次只允許跳過1顆棋子。
寫乙個程式,首先判斷是否可以完成任務。如果可以,輸出最少需要的跳動次數。
考慮一種類似於二叉樹的結構,三個跳棋無法再跳的時候(即$|xy|=|yz|$時),我把將它視為根,我們把初末狀態視為$a,b$兩個節點,那麼其實就是找$a,b的lca$,我們先找到$a,b$的根,如果根不同,沒有解,否則我們先把$a,b$提到同一深度,記深度差為$x$,然後二分往上跳的高度,記為$l$,答案就是$x+l*2$
#include#define i inline#define dist(x,y) (abs(x-y))
using
namespace
std;
const
int inf=1e9+10
;struct
node
a,b;
intdepth;
intans;
bool
operator ==(node a,node b)
i node calc(node a,
intk)
else
res.x[
1]=x;res.x[2]=y;res.x[3]=z;
if(k)return
calc(res,k);
return
res;
}int
main()
if(a.dep
ans=a.dep-b.dep;
a=calc(a,ans);
int l=0,r=b.dep;
while(l1
)
while(!(calc(a,l)==calc(b,l)))l++;
puts(
"yes");
cout
<2
;
}
跳跳棋 LCA 二分
description 跳跳棋是在一條數軸上進行的。棋子只能擺在整點上。每個點不能擺超過乙個棋子。我們用跳跳棋來做乙個簡單的遊戲 棋盤上有3顆棋子,分別在a,b,c這三個位置。我們要通過最少的跳動把他們的位置移動成x,y,z。棋子是沒有區別的 跳動的規則很簡單,任意選一顆棋子,對一顆中軸棋子跳動。跳...
BZOJ 2144 跳跳棋 二分 LCA
description 跳跳棋是在一條數軸上進行的。棋子只能擺在整點上。每個點不能擺超過乙個棋子。我們用跳跳棋來做乙個簡單的遊戲 棋盤上有3顆棋子,分別在a,b,c這三個位置。我們要通過最少的跳動把他們的位置移動成x,y,z。棋子是沒有區別的 跳動的規則很簡單,任意選一顆棋子,對一顆中軸棋子跳動。跳...
LCA 二分 倍增
兩個最近的點u和v的最近的公共的祖先稱為最近公共祖先 lca 普通的lca演算法,每算一次lca的時間複雜度為線性o n 這裡講lca 二分的方法。首先對於任意的節點v,利用其父節點的資訊,可以通過par2 v par par v 得到向上走兩步的節點。依此資訊可以通過par4 v par2 par...