【bzoj2144】跳跳棋

Description

跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移动成x,y,z。(棋子是没有区别的)跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过1颗棋子。 

写一个程序,首先判断是否可以完成任务。如果可以,输出最少需要的跳动次数。

Input

第一行包含三个整数,表示当前棋子的位置a b c。(互不相同)第二行包含三个整数,表示目标位置x y z。(互不相同)

Output

如果无解,输出一行NO。如果可以到达,第一行输出YES,第二行输出最少步数。

Sample Input

1 2 3
0 3 5

Sample Output

YES
2【范围】20% 输入整数的绝对值均不超过1040% 输入整数的绝对值均不超过10000100% 绝对值不超过10^9

题解

首先广搜有20分

对于一个状态

例如2 3 7

中间可以往两侧跳,即2 3 7->1 2 7 / 2 3 7->2 7 11

两侧仅有一个能往中间跳,即2 3 7->3 4 7

那么所有的状态就能表示为一棵二叉树,第一种情况为其两个儿子,第二种为其父亲

问题转换为给定树上的两个结点,求其距离

直接暴力可以得40分

可以构造这样的数据

1 2 1000000000

99999998 99999999 1000000000

这样左边要一直往中间跳上上亿次

我们发现若记前两个数差t1,后两个数差t2,不妨设t1<t2

则左边最多往中间跳(t2-1)/t1次

然后只能右边往中间跳,是一个辗转相除的过程,即在logK的时间内我们可以用这种方法得到某个结点它向上K次后的结点,或者根节点,同时还可以顺便算下深度

那么只要求始终两个状态的深度d1,d2,将较深的调整到同一深度

然后二分/倍增求与lca的深度差x

ans=2*x+abs(d1-d2)

 
 #include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstdio> #define inf 2000000007
#define ll long long
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch>''||ch<''){if (ch=='-') f=-;ch=getchar();}
while(ch<=''&&ch>=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int t1,t2,tmp,ans;
int a[],b[];
struct data
{
int a[];
}; data cal(int *a,int k)//得到a状态向上走k次的状态
{
data ans;
int t1=a[]-a[],t2=a[]-a[];
for(int i=;i<=;i++)ans.a[i]=a[i];
if(t1==t2)return ans;
if(t1<t2)
{
int t=min(k,(t2-)/t1);
k-=t;tmp+=t;//顺便记录深度
ans.a[]+=t*t1;ans.a[]+=t*t1;
}
else
{
int t=min(k,(t1-)/t2);
k-=t;tmp+=t;
ans.a[]-=t*t2;ans.a[]-=t*t2;
}
if(k)return cal(ans.a,k);//辗转相除
else return ans;
}
bool operator!=(data a,data b)
{
for(int i=;i<=;i++)
if(a.a[i]!=b.a[i])return ;
return ;
}
int main()
{
for(int i=;i<=;i++)a[i]=read();
for(int i=;i<=;i++)b[i]=read();
sort(a+,a+),sort(b+,b+);
data t1=cal(a,inf);int d1=tmp;tmp=;
data t2=cal(b,inf);int d2=tmp;tmp=;
//t1,t2分别为a,b的根,d1,d2为深度
if(t1!=t2){puts("NO");return ;}
if(d1>d2)
{
swap(d1,d2);
for(int i=;i<=;i++)
swap(a[i],b[i]);
}
ans=d2-d1;
t1=cal(b,ans);
for(int i=;i<=;i++)
b[i]=t1.a[i];//较深的向上调整 int l=,r=d1;
while(l<=r)//二分
{
int mid=(l+r)>>;
if(cal(a,mid)!=cal(b,mid))l=mid+;
else r=mid-;
}
printf("YES\n%d",ans+*l);
}

bzoj2144 跳跳棋 二分的更多相关文章

  1. BZOJ2144跳跳棋——LCA+二分

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的 游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...

  2. 跳跳棋——二分+建模LCA

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...

  3. bzoj2144: 跳跳棋(二分/倍增)

    思维好题! 可以发现如果中间的点要跳到两边有两种情况,两边的点要跳到中间最多只有一种情况. 我们用一个节点表示一种状态,那么两边跳到中间的状态就是当前点的父亲,中间的点跳到两边的状态就是这个点的两个儿 ...

  4. BZOJ2144: 跳跳棋

    传送门 神题一道. 考虑题目性质.首先对于一个状态,只存在四种情况,即最左/右边的点跳到中间,中间的点跳到左/右.而对于一个状态,显然第一种情况的两种分支不能同时存在,那么题目就可以理解为从$(a,b ...

  5. BZOJ2144 跳跳棋[建模+LCA]

    思维题,思路比较神仙. 个人思路过程:个人只想到了只要中间棋子开始向外跳了,以后就不应该向内跳了,这样很蠢.所以应该要么先向内跳一会,要么直接开始中间的向外跳.不知道怎么处理,就卡住了. 20pts: ...

  6. bzoj 2144: 跳跳棋——倍增/二分

    Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...

  7. 【bzoj2144】跳跳棋

    2144: 跳跳棋 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 492  Solved: 244[Submit][Status][Discuss] ...

  8. [BZOJ2144]国家集训队 跳跳棋

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...

  9. [BZOJ2144][国家集训队2011]跳跳棋

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上. 每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\),\(c\)这三个位置. 我们要通 ...

随机推荐

  1. vue+element ui项目总结点(四)零散细节概念巩固如vue父组件调用子组件的方法、拷贝数据、数组置空问题 等

    vue config下面的index.js配置host: '0.0.0.0',共享ip (假设你的电脑启动了这个服务我电脑一样可以启动)-------------------------------- ...

  2. HDU 4003 Find Metal Mineral (树形DP,经典)

    题意:给定一棵树图,n个节点,有边权,要派k<11个机器人从节点s出发,遍历所有的点,每当1只机器人经过1条边时就会花费该边的边权,边是可重复走的.问遍历完所有点的最小花费? 思路: 非常经典, ...

  3. httpmodule初识

    .net的请求流程: HttpRequest-->inetinfo.exe->ASPNET_ISAPI.DLL-->Http Pipeline-->ASPNET_WP.EXE- ...

  4. jQuery备忘录

    jquery 中遍历数组 var arr = [1,2,3,4,5] $.each(arr,function(i,j){ console.log(i,j) }) 结果 0 1 1 2 .... jQu ...

  5. -bash: xx: command not found 在有yum源情况下处理

    -bash: xx: command not found 在有yum源情况下处理 yum provides "*/xx"  ###"xx"代表某命令 或者 yu ...

  6. http post get 同步异步

    下面首先介绍一下一些基本的概念---同步请求,异步请求,GET请求,POST请求. 1.同步请求从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作.也 ...

  7. 【译】Swift 字符串速查表

    [译]Swift 字符串速查表 2015-12-18 10:32 编辑: suiling 分类:Swift 来源:CocoaChina翻译活动 10 5585 Swift字符串 招聘信息: iOS高级 ...

  8. HTML 显示和隐藏浏览器滚动条

    滚动条和overflow有关 显示: overflow-x:auto; overflow-y:auto; overflow-x:scroll; overflow-y:scroll; 隐藏: overf ...

  9. Python学习笔记2(序列)

    元组不可变序列 tuple函数 总结 字符串 基本字符串的操作 字符串格式化 字符串方法 find join lower replace split strip translate 小结 元组:不可变 ...

  10. Mac OS 终端强化美化:iterm2 + zsh + oh~my~zsh 设置教程

    为了获得更好的排版效果,文章改用markdown撰写,故重发一次. 前言 mac自带的terminal终端没有文件名高亮等功能,而且界面不是很好看,故今晚学舍友折腾了终端,可以让自己使用起来更加方便, ...