P1497 洛谷 P1852跳跳棋

2021-08-21 19:25:25 字數 1510 閱讀 9007

標籤(空格分隔): 資訊 圖論 二分 洛谷

考題,看到就覺得是不可能寫出來的那種,於是打了個bfs直接走人。

考完之後聽呂大佬講過之後覺得此題可謂絕妙啊%%%

屁顛屁顛地跑去寫之後才發現思路出來了**也並不好些。題面

看到覺得和倒油很像,一看資料範圍嚇死人,109109

,搜尋不可能了

看著和log有關,仔細分析一下發現可以把這個叫做跳跳棋的遊戲的一步棋看成乙個岔路口,一共有三條分支

1.中間的棋子往左邊跳

2.中間打棋子往右邊跳

3.左邊或者右邊的靠中間棋子近的往中間跳

(因為跳棋不可以跨過乙個棋子)

我們不妨把第三跳分支看成主幹,乙個二叉樹的模型就出來了。

題目中的abc,xyz就是其中的乙個結點,那麼我們要求是否連通,只要判斷它們的根結點是不是相同,如何確定乙個點是否為根結點呢?只要確保它沒有父親結點就是根結點了,不難發現滿足相鄰兩個結點的距離相等的點就是沒有父親的結點即根結點了。

要求最少步數,直接跑lca就好了,由於這是個抽象的樹,結點不全,在這裡最好用二分直接求解。

#include

#include

#include

#include

#include

using namespace std;

int x,y,z,s1,s2,s3,t1,t2,t3,a1,a2,a3,b1,b2,b3;

int first(int x1,int x2,int x3)

int third(int x1,int x2,int x3)

int second(int x1,int x2,int x3)

int dfs(int a,int b,int c)

if(b-a

if((b-a)%(c-b))

return dfs(a,a+(b-a)%(c-b),a+(b-a)%(c-b)+c-b)+(b-a)/(c-b);

else

return dfs(a,a+(c-b),a+

2*(c-b))+(b-a)/(c-b)-1;}

void hehe(int a,int b,int c,int value,int times)

if(b-a

else

return ;

}if((b-a)%(c-b))

else

}int divide(int l,int r)

int main()

cout<<

"yes"

if(len1>len2)

//coutb1=s1,b2=s2,b3=s3;

//cout*divide(0,len1);

return

0;}

**有點長,能ac就好。。。

洛谷P1852 跳跳棋

將三顆棋子看作三元組 x,y,z x,得其能轉移到的狀態有 large begin 2x y,x,z x,z,2z y x,2y z,y y x z y y,2y x,z y x 後兩個轉移只會滿足其中乙個,那麼將中間棋子向兩邊跳看作左右兒子,兩邊棋子向中間跳看作父親,根節點為滿足 y x z y ...

洛谷 P1852 國家集訓隊 跳跳棋

跳跳棋是在一條數軸上進行的。棋子只能擺在整點上。每個點不能擺超過乙個棋子。我們用跳跳棋來做乙個簡單的遊戲 棋盤上有3顆棋子,分別在a,b,c這三個位置。我們要通過最少的跳動把他們的位置移動成x,y,z。棋子是沒有區別的 跳動的規則很簡單,任意選一顆棋子,對一顆中軸棋子跳動。跳動後兩顆棋子距離不變。一...

P1852 國家集訓隊 跳跳棋

原 奇怪的字串 請前往 p2543 跳跳棋是在一條數軸上進行的。棋子只能擺在整點上。每個點不能擺超過乙個棋子。我們用跳跳棋來做乙個簡單的遊戲 棋盤上有3顆棋子,分別在a,b,c這三個位置。我們要通過最少的跳動把他們的位置移動成x,y,z。棋子是沒有區別的 跳動的規則很簡單,任意選一顆棋子,對一顆中軸...