bzoj2144: 跳跳棋(二分/倍增)
思维好题!
可以发现如果中间的点要跳到两边有两种情况,两边的点要跳到中间最多只有一种情况。
我们用一个节点表示一种状态,那么两边跳到中间的状态就是当前点的父亲,中间的点跳到两边的状态就是这个点的两个儿子,从而组成一棵二叉树。
于是两个状态能够达到当且仅当他们在同一棵树上,只要看看根节点是否一样就好了。
那怎么求两个状态的最短距离呢?我们考虑两边的点跳到中间实际上是一个更相相损的过程,于是我们像gcd一样做就可以优化成log级别的了。求两个状态的最短距离实际上就是求两个节点在树上的距离,像倍增求lca一样,先跳到一样的高度,然后二分一下高度,找到LCA算就好了。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=,inf=1e9;
struct poi{int x,y,z;}a,b,x,y;
int high,len,lena,lenb;
inline void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
poi climb(poi now,int time)
{
for(len=;time;len+=high)
{
int l=now.y-now.x,r=now.z-now.y;
if(l==r)return now;
if(l<r)high=min((r-)/l,time),time-=high,now.x+=l*high,now.y+=l*high;
else high=min((l-)/r,time),time-=high,now.y-=r*high,now.z-=r*high;
}
return now;
}
void sort(poi &now)
{
if(now.x>now.y)swap(now.x,now.y);
if(now.x>now.z)swap(now.x,now.z);
if(now.y>now.z)swap(now.y,now.z);
}
int main()
{
read(a.x);read(a.y);read(a.z);
read(b.x);read(b.y);read(b.z);
sort(a);sort(b);
x=climb(a,inf);lena=len;
y=climb(b,inf);lenb=len;
if(x.x!=y.x||x.y!=y.y||x.z!=y.z)return puts("NO"),;
puts("YES");
if(lena<lenb)swap(a,b),swap(lena,lenb);
a=climb(a,lena-lenb);
int l=,r=lenb;
while(l<r)
{
int mid=(l+r)>>;
x=climb(a,mid);y=climb(b,mid);
if(x.x==y.x&&x.y==y.y&&x.z==y.z)r=mid;
else l=mid+;
}
printf("%d",(l<<)+lena-lenb);
}
bzoj2144: 跳跳棋(二分/倍增)的更多相关文章
- bzoj2144 跳跳棋 二分
[bzoj2144]跳跳棋 Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位 ...
- BZOJ2144跳跳棋——LCA+二分
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的 游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- 【BZOJ 2144】 2144: 跳跳棋 (倍增LCA)
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 642 Solved: 307 Description 跳跳棋是在一条数轴上进行的 ...
- 跳跳棋——二分+建模LCA
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- BZOJ2144: 跳跳棋
传送门 神题一道. 考虑题目性质.首先对于一个状态,只存在四种情况,即最左/右边的点跳到中间,中间的点跳到左/右.而对于一个状态,显然第一种情况的两种分支不能同时存在,那么题目就可以理解为从$(a,b ...
- BZOJ2144 跳跳棋[建模+LCA]
思维题,思路比较神仙. 个人思路过程:个人只想到了只要中间棋子开始向外跳了,以后就不应该向内跳了,这样很蠢.所以应该要么先向内跳一会,要么直接开始中间的向外跳.不知道怎么处理,就卡住了. 20pts: ...
- bzoj 2144: 跳跳棋——倍增/二分
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
- 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】
P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...
- 【bzoj2144】跳跳棋
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 492 Solved: 244[Submit][Status][Discuss] ...
随机推荐
- Object里面的方法
object里面有12个方法,没写完,写一些部分代表 toString():输出对象的地址字符串(hashcode码) equals():用的是==,比较的是引用,在有些类里面是重写了这个方法的,重写 ...
- gitlab-登录账户遇到ERROR: Permission to XXX.git denied to user报错怎么办
碰到这个问题就意味着没有访问账户的权限,没有把访问电脑与访问账户用ssh_key关联起来,解决流程: 1.查看本地是否有ssh_key 笔者用的是git bash来输入命令 ls -al ~/.ssh ...
- 树莓派 Raspberry Pi 与 micro:bit起手式
本文将学习如何在Raspberry Pi上安装MicroPython编辑器mu,并将MicroPython中编写的程序从您的Raspberry Pi推送到micro:bit. 您需要: 硬件, 带有S ...
- 题解 CF682C 【Alyona and the Tree】
简单搜索题,我们每找到一组不满足题目给出条件的点和边就将其整个子树删除,然后最终答案加上该子树的大小即可.注意,搜索的时候如果当前的边权和sum已经为负了,应该将其改为0(可以想想为什么) 注:题目翻 ...
- 子序列 (All in All,UVa10340)
题目描述:算法竞赛入门经典习题3-9 题目思路:循环匹配 //没有按照原题的输入输出 #include <stdio.h> #include <string.h> #defin ...
- 孤荷凌寒自学python第八十六天对selenium模块进行较详细的了解
孤荷凌寒自学python第八十六天对selenium模块进行较详细的了解 (今天由于文中所阐述的原因没有进行屏幕录屏,见谅) 为了能够使用selenium模块进行真正的操作,今天主要大范围搜索资料进行 ...
- jmeter使用复习
多终端进程: 配置客户端远程的ip地址和port 在客户端jmeter安装目录的bin目录下,修改配置文件 jmeter.properties 默认的remote_hosts 的值:(将肉鸡的地址加入 ...
- C++ 学习笔记之——STL 库 queue
1. 队列 queue 队列是一种容器适配器,专门用来满足先进先出的操作,也就是元素在容器的一端插入并从另一端提取. bool empty() const; 返回队列是否为空: size_type s ...
- Python中的slice操作
Python中slice操作的完整语法: # i默认是0 # j默认是len(S) # k的步长,默认为+1 S[i:j:k] 其中i,j,k都可以是负数: 若i < 0或者k<0,等价于 ...
- 在 Range 对象中,Min (14)必须小于或等于 max (-1)。
DataTable dt = ds.Tables[]; DataRow[] drs = dt.Select("Id=" + categoryID ); 解决方法:将参数用单引号阔起 ...