bzoj2144 【国家集训队2011】跳跳棋
来源:互联网 发布:evasi0n7 mac 编辑:程序博客网 时间:2024/05/02 00:25
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
0 3 5
Sample Output
YES2
【范围】
100% 绝对值不超过10^9
正解:倍增lca
为了方便研究跳法,我们把棋子按坐标大小排序。我们发现,当中间那粒棋子与左边的距离和与右边的距离不相等时,有3种跳法,而两者距离相等时,只有两种跳法。所以,对于往中间跳的跳法,我们可以把它理解成在树上跳父亲,而对于往旁边跳,我们可以理解成在树上跳儿子。所以我们就可以把题意转化一下,即第一问为两种状态是否有lca,而第二种则是问两种状态在树上的距离。我们可以采用类似倍增的方法跳lca,来求出答案。
//It is made by wfj_2048~#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <vector>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>#define inf 1<<30#define il inline#define RG register#define ll long longusing namespace std;struct data{ int a,b,c; bool operator != (const data &x) const{return a!=x.a || b!=x.b || c!=x.c; }};int a[2][5],depa,depb;il int gi(){ RG int x=0,q=0; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if (ch=='-') q=1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q ? -x : x;}il data find(RG data u,RG int k,RG int &dep){ RG int dis1=u.b-u.a,dis2=u.c-u.b,t; if (dis1==dis2) return u; if (dis1<dis2) t=min(k,(dis2-1)/dis1),k-=t,dep+=t,u.a+=t*dis1,u.b+=t*dis1; else t=min(k,(dis1-1)/dis2),k-=t,dep+=t,u.b-=t*dis2,u.c-=t*dis2; if (k) return find(u,k,dep); else return u;}il void work(){ for (RG int i=1;i<=3;++i) a[0][i]=gi();sort(a[0]+1,a[0]+4); for (RG int i=1;i<=3;++i) a[1][i]=gi();sort(a[1]+1,a[1]+4); data x=(data){a[0][1],a[0][2],a[0][3]},y=(data){a[1][1],a[1][2],a[1][3]},u=find(x,inf,depa),v=find(y,inf,depb); if (u!=v){ puts("NO"); return; } puts("YES"); if (depa<depb) swap(x,y),swap(depa,depb); RG int l=0,r=depb,mid,cnt,ans,Ans=depa-depb; x=find(x,Ans,cnt); while (l<=r){mid=(l+r)>>1;RG data x1=find(x,mid,cnt),y1=find(y,mid,cnt);if (x1!=y1) l=mid+1; else ans=mid,r=mid-1; } printf("%d\n",Ans+2*ans); return;}int main(){ work(); return 0;}
1 0
- bzoj2144 【国家集训队2011】跳跳棋
- 【BZOJ2144】跳跳棋
- 【杂题】bzoj2144跳跳棋
- 【bzoj2144】跳跳棋
- [bzoj2144]: 跳跳棋
- [bzoj2144]跳跳棋 LCA
- bzoj2144 跳跳棋 二分+lca
- 【数学】2011集训队出题 跳跳棋
- bzoj2144 跳跳棋 二分&lca 神题
- 【BZOJ2144】跳跳棋 模拟gcd以及倍增LCA
- 【国家集训队2011】【BZOJ2151】种树
- 【国家集训队2011】【BZOJ2141】排队
- bzoj2151[国家集训队2011] 种树
- [国家集训队2011]stone解题报告
- [国家集训队2011]种树 解题报告
- [国家集训队2011]happiness(吴确)…
- 【BZOJ 2120】【国家集训队 2011】【数颜色】
- 【COGS 1873】 [国家集训队2011]happiness(吴确)
- 10 条提升 Android 性能的建议
- welcome to my blog..
- 中式风格icon图标
- Linux-一些简单的按键
- Hermes实时检索分析平台
- bzoj2144 【国家集训队2011】跳跳棋
- HDU 3156 Repair Depots DLX 计算几何 二分 暴力
- alsa lib
- springIOC之二
- JAVA WEB从入门到精通day09 Tomcat和HTTP协议
- python3下opencv的编译过程
- 优先队列排序
- 在腾讯云上面搭建个人网站
- tomcat + 花生壳 - Android 服务器搭建