Link
这题妙啊,
题目
解
由"一次只能跳过一颗棋子",得到此题的一个重要性质:
这三个棋在某一时刻至多有3种跳法:中间的往左右跳,或离中间棋子较近的棋子跳往中间。像这样
而当AB=BC时只有两种跳法(A跳不到A’的位置)
当外面的点往里跳后,这三个棋子的范围会越来越小,直到出现不能往里跳的情况。
我们发现,此时的状态是唯一的:这三个棋子不可能在其它地方重现此时的相对状态。
我们就把这样的状态作为根;
判断两组棋子的根,如果它们不相同,说明它们永远不可能摆成另外一组的样子;直接输出No。
如果它们能摆成同一个根,那么我们就需要LCA(求最近公共祖先)了。
第一组棋子最终会先移动到LCA的状态再移到第二组棋子的状态。
注意
- 求LCA时我们用不了倍增,但可以用二分加速
- 万一AB很近而BC很远很远,这里可以优化一下,像这样:
AB移动时直接加上 (k-1)*AB 就好了。(平移大法)由于棋子没有特别要区别,所以不用在意AB位置是否交换的问题。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int astep,bstep;
struct asdf{
int a,b,c;
} A,B,Fka,Fkb;
void px(asdf &LL){
//排序...
if(LL.a>LL.b) swap(LL.a,LL.b);
if(LL.a>LL.c) swap(LL.a,LL.c);
if