>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
yes2
20% 輸入整數的絕對值均不超過10
40% 輸入整數的絕對值均不超過10000
100% 絕對值不超過10^9
>解題思路
題目大意:有乙個線性的跳棋,問三個點的狀態
a,b,
c}能否到達,並且輸出最小步數
設為s
1s_1
s1,為s
2s_2
s2通過手動模擬可以發現,一組資料,a
<
ba<
b<
c,可以達到三種狀態:
b
bb向a
aa的方向跳
b
bb向c
cc的方向跳
離b
bb近的點往b
bb的方向跳,且當僅當b−a
≠c−b
b-a≠c-b
b−a=
c−b(三個點均勻分布,這樣子就跳不動)
我們可以發現1、2種跳的方法是擴大範圍,第3種是縮小範圍,所以我們可以把第3種設為根,把第1、2種設為兩個子節點,因此b−a
==c−
bb-a==c-b
b−a==c
−b的狀態為根節點
如果s
1s_1
s1和s
2s_2
s2的根節點相同,就說明s
1s_1
s1可以到達s
2s_2
s2所以我們可以進行以下步驟:
往上跳,分別尋找s
1s_1
s1,s
2s_2
s2的根,判斷這兩個根節點是否相等
把s
1s_1
s1和s
2s_2
s2跳到同一高度
二分向上跳的步數,看兩個狀態跳躍以後分別達到的狀態是否相同
這裡有乙個很重要的加速:
如果是這種距離很長的情況,可以直接用除數加速,當然要注意重合的情況
例如設d1=
b−ad_1=b-a
d1=b−
a,d2=c
−bd_2=c-b
d2=c−
b,可以直接用d1/
d2d_1/d_2
d1/d2
加速>**
#include
#include
#include
#include
using namespace std;
struct node
s1, s2, root[5]
;int dep[5]
;bool check
(node aa, node bb)
void
ssort
(node &aa)
//排序
void
getroot
(node aa, int ll)
else
dep[ll]
+= l;
//累計狀態在樹中的深度
ssort
(aa);}
root[ll]
=(node);}
//找根
node jump
(node aa, int k)
//狀態aa往上跳k步達到的狀態
else
k -= l;
ssort
(aa);}
return aa;
}int main()
int d =
abs(dep[1]
- dep[2]
);//初始狀態和最終狀態相差的深度
if(dep[1]
> dep[2]
) s1 =
jump
(s1, d)
;else
if(dep[1]
< dep[2]
) s2 =
jump
(s2, d)
;//把深度深的跳到和深度淺的同一層
int l =
0, r =
min(dep[1]
, dep[2]
), mid;
int m =0;
while
(l <= r)
printf
("yes\n%d"
, d +
2* m)
;//兩點到lca的路徑長度
return0;
}
跳跳棋 二分 建模LCA
跳跳棋是在一條數軸上進行的。棋子只能擺在整點上。每個點不能擺超過乙個棋子。我們用跳跳棋來做乙個簡單的遊戲 棋盤上有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...