【神仙题目】【LCA】洛谷P1852 跳跳棋

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值