[BZOJ2144]跳跳棋

试题描述

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

输入

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

输出

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

输入示例

1 2 3
0 3 5

输出示例

YES
2

数据规模及约定

100% 绝对值不超过10^9

题解

这是一道思路神题。

首先你要想到能够把状态转移放到一棵树里。具体做法是每种状态有两种往外跳的方案(中间的点向左或向右跳),或者只有一边的棋子能够跳到另外两个棋子中间(这种情况可能不存在,就是在三个数构成等差数列时),那么我们把两种往外跳的转移作为这个状态的两个儿子,往中间跳的转移作为父亲(不存在的话就是根)。

然后我们发现这棵树可能很长很大,比如

(a, b, c) = (0, 1, 1e9)

(x, y, z) = (1e9 - 2, 1e9 - 1, 1e9)

那么会有一条边数为 1e9 - 2 的链。

但是明显这条链有规律,就是每次移动都是左边两个数加上前两个数的差,那么我们就可以通过简单的除法跳到这条链的顶端;然后就可能轮到右边的两个数往左跳;这整个过程就是一个辗转相除的过程了。

然后我们对于两个状态,我们让它们往上跳到根(这个过程显然可以记录一下两个状态分别所在深度),如果根不相同就表明不存在方案;否则我们就可以像倍增求 lca 一样把两个状态调到同一深度,然后二分它们到 lca 的距离。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;int read() {int x = 0, f = 1; char c = getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }return x * f;
}#define oo 1000000000int dep;
struct Sta {int A[3];Sta() {}Sta(int _1, int _2, int _3) { A[0] = _1; A[1] = _2; A[2] = _3; sort(A, A + 3); }bool operator == (const Sta& t) const { return A[0] == t.A[0] && A[1] == t.A[1] && A[2] == t.A[2]; }bool operator != (const Sta& t) const { return !(*this == t); }Sta jump(int step) {Sta ans = *this;int l1 = ans.A[1] - ans.A[0], l2 = ans.A[2] - ans.A[1];if(l1 == l2) return ans;if(l1 < l2) {int k = min(step, (l2 - 1) / l1);step -= k; dep += k;ans.A[0] += k * l1; ans.A[1] += k * l1;}else {int k = min(step, (l1 - 1) / l2);step -= k; dep += k;ans.A[1] -= k * l2; ans.A[2] -= k * l2;}if(step) return ans.jump(step);return ans;}
} st, en;int main() {int a = read(), b = read(), c = read();st = Sta(a, b, c);a = read(); b = read(); c = read();en = Sta(a, b, c);Sta tmp1, tmp2; int h1, h2;dep = 0; tmp1 = st.jump(oo); h1 = dep;dep = 0; tmp2 = en.jump(oo); h2 = dep;if(tmp1 != tmp2) return puts("NO"), 0;puts("YES");if(h1 < h2) swap(h1, h2), swap(st, en);st = st.jump(h1 - h2);int l = -1, r = oo + 1;while(r - l > 1) {int mid = l + r >> 1;if(st.jump(mid) == en.jump(mid)) r = mid; else l = mid;}printf("%d\n", (++l << 1) + h1 - h2);return 0;
}

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6859877.html

[BZOJ2144]跳跳棋相关推荐

  1. bzoj2144 跳跳棋

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

  2. bzoj-2144 跳跳棋

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

  3. [bzoj2144]: 跳跳棋

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

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

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

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

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

  6. 洛谷1852 BZOJ2144 跳跳棋 思维题

    题目链接 题意: 坐标轴上告诉你三个互不相同的位置作为三个棋子的起点,再告诉你三个不同的位置作为三个棋子的终点,每次操作可以让一个棋子以另一个棋子为轴跳到对称位置,并且只能跳过一个棋子,问你是否能最终 ...

  7. BZOJ2144: 跳跳棋

    求三个人从a,b,c这三个位置跳到x,y,z最少多少步.跳:任意选一颗棋子,对一颗中轴棋子跳动.跳动后两颗棋子距离不变.一次只允许跳过1颗棋子.  从它跳的性质出发,向内跳只有一种操作,而向外跳有两种 ...

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

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

  9. 【BZOJ2144】跳跳棋

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

最新文章

  1. SQL SERVER 2008 登陆失败(SQL和windows都没有对应的权限)
  2. linux绑定盘符吗,Linux盘符绑定实现原理.PDF
  3. [认证授权] 5.OIDC(OpenId Connect)身份认证授权(扩展部分)
  4. ML之K-means:基于K-means算法利用电影数据集实现对top 100 电影进行文档分类
  5. 文件上怎么盖章_投标文件该怎么盖章呢?投标人必看!
  6. P3177-[HAOI2015]树上染色【树形dp】
  7. mysql的char和varchar_MySQL的char和varchar
  8. linux的进程/线程/协程系列3:查看linux内核源码——vim+ctags/find+grep
  9. (27)FPGA面试技能提升篇(UVM、VMM)
  10. 基于单片机的自动加热水壶控制器代码_应用于实时温度控制的单片机设计
  11. iOS 抓包工具限免,速度下载!【附使用教程】
  12. android连接打印机打印pdf文件,如何在Android设备上打印PDF文件
  13. 关于itchat发送图片清晰度的玄学
  14. 神经网络放大图片,神经网络AI滤镜
  15. 质数距离 数论(线性筛选素数 合数存在素数因子)
  16. 第2次作业—— 时事点评
  17. 日期相关(类与方法)
  18. 当当图书,这又是何苦。
  19. 什么是favicon.ico,以及如何使用它
  20. springboot基于Java的多元化智能选课系统毕业设计源码040909

热门文章

  1. 2020-10-20 Ant Design Vue 关闭国际化设置默认语言为中文的
  2. 张栋_机器学习的照片 - 微相册
  3. python教程39-做个淘宝双十一满减攻略
  4. 【转载】CSDI2018广州关于《Nginx》的分享(附文字速录与PPT)
  5. Spark REPL
  6. sqlserver获取周数
  7. unity2D学习笔记-角色动画
  8. 生物特征模板保护技术
  9. MySQL每天定时12点弹出黑窗口
  10. 定时任务实现(中午12点执行,每1分钟执行一次)