跳跳棋——二分+建模LCA
题目描述
跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。

我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移动成x,y,z。(棋子是没有区别的)
跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过1颗棋子。
写一个程序,首先判断是否可以完成任务。如果可以,输出最少需要的跳动次数。
思路
考虑一种类似于二叉树的结构,三个跳棋无法再跳的时候(即$|XY|=|YZ|$时),我把将它视为根,我们把初末状态视为$a,b$两个节点,那么其实就是找$a,b的LCA$,我们先找到$a,b$的根,如果根不同,没有解,否则我们先把$a,b$提到同一深度,记深度差为$x$,然后二分往上跳的高度,记为$l$,答案就是$x+l*2$
code
#include<bits/stdc++.h>
#define I inline
#define dist(x,y) (abs(x-y))
using namespace std;
const int inf=1e9+;
struct node
{
int x[];
int dep;
}a,b;
int depth;
int ans; bool operator == (node a,node b)
{
sort(a.x+,a.x+);sort(b.x+,b.x+);
for(int i=;i<=;i++)if(a.x[i]!=b.x[i])return ;
return ;
} I node calc(node a,int k)
{
int x=a.x[],y=a.x[],z=a.x[];
node res;
for(int i=;i<=;i++)res.x[i]=a.x[i];
int d1=dist(x,y),d2=dist(y,z);
if(d1==d2)return res;
if(d1<d2)
{
int t=min(k,(d2-)/d1);
x+=d1*t;y+=d1*t;
k-=t;depth+=t;
}
else
{
int t=min(k,(d1-)/d2);
y-=d2*t;z-=d2*t;
k-=t;depth+=t;
}
res.x[]=x;res.x[]=y;res.x[]=z;
if(k)return calc(res,k);
return res;
} int main()
{
cin>>a.x[]>>a.x[]>>a.x[]>>b.x[]>>b.x[]>>b.x[];
sort(a.x+,a.x+);sort(b.x+,b.x+);
node rt1=calc(a,inf);a.dep=depth;depth=;
node rt2=calc(b,inf);b.dep=depth;depth=;
if(!(rt1==rt2)){cout<<"NO";return ;}
if(a.dep<b.dep)swap(a,b);
ans=a.dep-b.dep;
a=calc(a,ans);
int l=,r=b.dep;
while(l<r-)
{
int mid=l+r>>;
if(calc(a,mid)==calc(b,mid))r=mid;
else l=mid;
}
while(!(calc(a,l)==calc(b,l)))l++;
puts("YES");
cout<<ans+l*; }
跳跳棋——二分+建模LCA的更多相关文章
- bzoj2144 跳跳棋 二分
[bzoj2144]跳跳棋 Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位 ...
- 【BZOJ 2144】 2144: 跳跳棋 (倍增LCA)
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 642 Solved: 307 Description 跳跳棋是在一条数轴上进行的 ...
- 跳跳棋[LCA+二分查找]-洛谷1852
传送门 这真是一道神仙题 虽然我猜到了这是一道LCA的题 但是... 第一遍看题,我是怎么也没想到能和树形图扯上关系 并且用上LCA 但其实其实和上一道lightoj上的那道题很类似 只不过那时一道很 ...
- BZOJ2144跳跳棋——LCA+二分
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的 游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- P1852 跳跳棋 [LCA思想+二分答案]
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有\(3\)颗棋子,分别在\(a,b,c\)这三个位置.我们要通过最少的跳动 ...
- 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】
P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...
- bzoj 2144: 跳跳棋——倍增/二分
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
- 不一样的LCA——luoguP1852跳跳棋
洛谷端题目链接 loj端题目链接 题目大意: 在一条数轴上进行跳跳棋游戏.棋子只能摆在整点上.每个点不能摆超过一个棋子.用跳跳棋完成:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动 ...
- 【LCA】bzoj 2144:跳跳棋
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 248 Solved: 121[Submit][Status][Discuss] ...
随机推荐
- ionic3 浏览器端返回
首屏component.ts文件中使用setupBrowserBackButtonBehavior() { // Register browser back button action(s) wind ...
- js通过方法返回对象的注意点
问题:js通过方法返回一个字面量对象和返回一个提前已经定义好的字面量对象有区别吗? 答案:有 我们先来看看第一种情况,fun1方法返回一个提前没定义的字面量对象,然后通过调用方法返回三个对象,分别是o ...
- Sql 六种约束
--1.主键约束问题 create table 学生表( 学号 int primary key, 姓名 varchar(10)); insert into 学生表 values(null,'a');问 ...
- 微信小程序中事件
微信小程序中事件 一.常见的事件有 类型 触发条件 最低版本 touchstart 手指触摸动作开始 touchmove 手指触摸后移动 touchcancel 手指触摸动作被打断,如来电提醒,弹窗 ...
- Ubuntu 查看已安装软件
apt list --installed dpkg -l
- Qt5教程: (5) Lambda匿名函数的使用
Lambda是C++11的新特性, 首先看看你的.pro项目文件里有没有CONFIG += c++11这句话, 没有就加上. 下面新建一个工程, 具体步骤就不多说了 然后给主窗口添加一个按钮b, 并且 ...
- 域渗透基础之Kerberos认证协议
本来昨晚就该总结整理,又拖到今天早上..6点起来赶可还行 0x01 Kerberos前言 Kerberos 是一种由 MIT(麻省理工大学)提出的一种网络身份验证协议.它旨在通过使用密钥加密技术为客 ...
- 关于用gulp合并压缩seaJs模块
现在很多人都在用seaJs来开发项目,seaJs上手容易,操作简单.但在后期做合并压缩的时候却中了个巨大无比的坑,但坑也总得有人来填.于是花了将近一个星期的时间来填了这坑,现将填坑的一些心得与大家分享 ...
- opencv::sift特征提取
SIFT特征检测介绍 SIFT(Scale-Invariant Feature Transform)特征检测关键特性: -建立尺度空间,寻找极值 -关键点定位(寻找关键点准确位置与删除弱边缘) -关键 ...
- Vue项目多域名跨域
在Vue项目中请求后台数据时,遇到的多域名跨域问题. 直接上代码: assetsSubDirectory: "static", assetsPublicPath: "/& ...