题目描述

跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。我们用跳跳棋来做一个简单的游戏:棋盘上有三颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移动成x,y,z(注意:棋子是没有区别的)。

跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过一颗棋子。

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

输入格式

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

输出格式

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


解答:

考虑对于当前状态的a,b,c有哪些可移动方案,设d1=b-a,d2=c-b,如果d1!=d2,那么b可以向两边跳,d1,d2其中小的那个可以向中间跳;如果d1=d2那么只能由b向两边跳。

可移动方案最多只有三种,那么可以将每个状态看成一个点,往左右跳看作这个点的左右子节点,往中间跳看作是这个点的父节点,如果不能往中间跳,那这个点就是根节点。

那么所有状态就变成了一个二叉树森林,判断能否完成就变成了判断两个状态是否在同一棵树中,而最小步数自然就是两点间的距离了。

但如果将所有状态都枚举出来显然不行,例如下面这个样例:

1 2 1e9

1e9-1 1e9-2 1e9

要跳1e9级别这么多次,显然不能暴力跳。

那么再回到求答案的那一步,两点间的距离不就是lca分别和两点深度差的和吗!

而深度就是每个点跳到根节点的步数。

那么两点往上跳在原题中就是两边的点往中间跳。

因为跳的点和被跳的点之间的相对距离不变,那么就相当于将两个点都平移了两点间距离这么多。

假设d1>d2,那么c最多向左平移(d1-1)/d2次(因为不能跳到同一个点)。

对于d1和d2,我们可以像求gcd一样辗转相除来求得在二叉树上给出的这两点的深度,然后将深度深的点往上跳使两点深度相同。

接下来只要找到深度相同的这两个点的lca就好了,可以像求倍增lca一样往上跳验证,也可以用二分答案来往上跳验证。

我这里用了二分的写法。注意原题三个数不一定按顺序给出。

代码如下:

#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll a,b,c;
ll x,y,z;
ll dep1,dep2;
ll root1,root2;
ll l1,l2;
ll len;
void cmp(ll &a,ll &b,ll &c)
{if(a>b){swap(a,b);}if(a>c){swap(a,c);}if(b>c){swap(b,c);}
}
ll find_root(ll a,ll b,ll c,ll &dep,ll &anc)
{ll d1=b-a;ll d2=c-b;while(d1!=d2){if(d1<d2){ll s=d2/d1;ll t=d2%d1;if(t==0){dep+=(s-1);anc=d1;return a+(s-1)*d1;}else{dep+=s;a+=s*d1;d2=t;}}else{ll s=d1/d2;ll t=d1%d2;if(t==0){dep+=(s-1);anc=d2;return a;}else{dep+=s;d1=t;}}}dep=0;anc=d1;return a;
}
void get_fa(ll &a,ll &b,ll &c,ll dep)
{ll d1=b-a;ll d2=c-b;while(dep>0){if(d1<d2){ll s=d2/d1;ll t=d2%d1;if(s>=dep){a+=dep*d1;b+=dep*d1;if(b==c){b=a;a-=d1;}return ;}else{dep-=s;a+=s*d1;b+=s*d1;d2=t;}}else{ll s=d1/d2;ll t=d1%d2;if(s>=dep){c-=dep*d2;b-=dep*d2;if(a==b){b=c;c+=d2;}return ;}else{dep-=s;b-=s*d2;c-=s*d2;d1=t;}}}
}
int main()
{scanf("%lld%lld%lld",&a,&b,&c);scanf("%lld%lld%lld",&x,&y,&z);cmp(a,b,c);cmp(x,y,z);l1=find_root(a,b,c,dep1,root1);l2=find_root(x,y,z,dep2,root2);if(l1!=l2||root1!=root2){printf("NO");return 0;}if(dep1<dep2){len+=dep2-dep1;get_fa(x,y,z,len);}else{len+=dep1-dep2;get_fa(a,b,c,len);}ll l=0;ll r=min(dep1,dep2);ll ans=0;while(l<=r){ll mid=(l+r)/2;ll a1=a,b1=b,c1=c;ll x1=x,y1=y,z1=z;get_fa(a1,b1,c1,mid);get_fa(x1,y1,z1,mid);if(a1==x1&&b1==y1&&c1==z1){ans=mid;r=mid-1;}else{l=mid+1;}}printf("YES\n");printf("%lld",len+ans*2);
}

敲码不易,点个关注qwq~


bye~

「BZOJ2144」跳跳棋相关推荐

  1. 【BZOJ2144】跳跳棋

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

  2. 「Swift」跳转至第三方App|淘宝、天猫、京东

    前言:如何从自己的App跳转到相应的淘宝.天猫.京东等第三方App中相应的商品或店铺 1.配置环境 需要在Info.plist 里面建立一个叫 LSApplicationQueriesSchemes ...

  3. UC伯克利造出会「轻功」的机器人,飞檐走壁,一条腿跳遍天下|湾区人工智能...

    选自Berkeley News 作者:Kara Manke 机器之心编译 参与:路.shooting Salto 机器人由 UC 伯克利的研究者首创于 2016 年,这只跳跃机器人还没有一只脚大,但它 ...

  4. [BZOJ2144]跳跳棋

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

  5. bzoj2144 跳跳棋

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

  6. 3D模型学会了「唱、跳、Rap、篮球」,程序员们全沉迷「鸡你太美」

    继 B 站之后,GitHub 网友也开始沉迷「鸡你太美」,让 3D 姿态也学会了「唱.跳.Rap.篮球」,而且动作准确度和连贯性似乎一点也不输练习时长两年半的练习生. 看了这段 demo 之后,网友戏 ...

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

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

  8. bzoj-2144 跳跳棋

    2144: 跳跳棋 题目链接 时间限制: 10 Sec 内存限制: 259 MB 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一 个简单的游戏: ...

  9. [bzoj2144]: 跳跳棋

    2144: 跳跳棋 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 689  Solved: 326 [Submit][Status][Discuss ...

最新文章

  1. 【算法拾遗(java描写叙述)】--- 选择排序(直接选择排序、堆排序)
  2. wamp配置多少站点
  3. python的sys.path
  4. 一篇文章搞懂腾讯云AI平台的人工智能IDE:TI-ONE
  5. https://blog.csdn.net/weixin_40412037/article/details/112235003
  6. FCN全卷积网络随笔
  7. Hive的数据模型-分区表
  8. Vue 3 正式发布
  9. 区块链相关数据报表_区块链相关论文研读5:分布式隐私保护可审计的账本,zkLedger...
  10. ant如何形成时间轴和图库_如何让景观设计更具有逻辑性?
  11. 基于DEAP库的python进化算法--遗传算法实践--非线性函数寻优
  12. 计算机软件编程英语词汇集锦
  13. Wine——在Linux上运行Windows软件
  14. 2022世界机器人大会开幕,有屋智能主动终止IPO,《2022人工智能发展白皮书》发布,2022可穿戴设备出货量将达3.44亿台
  15. Win7系统上的appdata是什么文件夹可以删除roaming
  16. 君生我未生,我生君已老
  17. 缓存(Cookie,SessionStorage,localStorage)详解
  18. 星星泡饭伴奏_星星泡饭 - Ayo_Lvlv - 5SING中国原创音乐基地
  19. 石油大学计算机第二阶段在线作业答案,中国石油大学计算机应用基础第二阶段在线作业答案2018年.docx...
  20. Charles的基本使用及教程

热门文章

  1. 易语言单窗口单ip教程_Excel打印送货单教程 常见问题汇总
  2. 汽车电控之节气门位置传感器
  3. 1024灯控台初学,1024灯控台操作说明
  4. SQL 左外连接,右外连接,全连接,内连接带图详细介绍
  5. OpenCV入门(三)快速学会OpenCV2图像处理基础(一)
  6. 免费空间python_10M/S!百度网盘偷偷更新,终于实现免费不限速了?!
  7. Tomcat安装、配置和部署笔记
  8. 深度学习——特征点检测和目标检测
  9. 贾跃亭持有乐视网25%股权:所质押股票已触及平仓线
  10. NetApp存储产品---知识笔记