题目描述

跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。

我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移动成x,y,z。(棋子是没有区别的)

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

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

输入输出格式

输入格式:

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

第二行包含三个整数,表示目标位置x y z。(互不相同)

输出格式:

如果无解,输出一行NO。

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

输入输出样例

输入样例#1:

1 2 3
0 3 5
输出样例#1:

YES
2

说明

20% 输入整数的绝对值均不超过10

40% 输入整数的绝对值均不超过10000

100% 绝对值不超过10^9

非常有趣的一道题目。

可以发现只有唯一的一种方案向里跳,并且一直这样跳最后总会达到一种再也不能向里跳的状态。

于是我们就可以把向里跳看成在树上向父亲走,而最后b-a = c-b 的状态就是根节点。

首先如果两个状态的树根不一样,无解;否则就是一个求LCA的问题了,直接倍增即可。

/*
向前跳: a[1] -= a[2] (须满足 a[1] > a[2])
向后跳: a[2] -= a[1] , a[0] += a[1] (须满足 a[1] < a[2])
a[1] == a[2] 就不能跳了
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std; struct node{
int x,y,z;
bool operator !=(const node &u)const{
return x!=u.x||y!=u.y||z!=u.z;
}
}A,B; int a[3],b[3];
unsigned int ans; node getroot(node x){
if(x.y==x.z) return x; if(x.y>x.z) return getroot((node){x.x,(x.y-1)%x.z+1,x.z}); else{
int o=(x.z-1)/x.y;
x.x+=o*x.y,x.z-=o*x.y;
return getroot(x);
}
} int getdeep(node x){
if(x.y==x.z) return 0; if(x.y>x.z){
int o=(x.y-1)/x.z;
x.y-=o*x.z;
return getdeep(x)+o;
} else{
int o=(x.z-1)/x.y;
x.x+=o*x.y,x.z-=o*x.y;
return getdeep(x)+o;
}
} node getnode(node x,int lef){
if(x.y==x.z) return x; if(x.y>x.z){
int o=(x.y-1)/x.z; if(o>=lef) return (node){x.x,x.y-lef*x.z,x.z}; x.y-=o*x.z;
return getnode(x,lef-o);
} else{
int o=(x.z-1)/x.y; if(o>=lef) return (node){x.x+lef*x.y,x.y,x.z-lef*x.y}; x.x+=o*x.y,x.z-=o*x.y;
return getnode(x,lef-o);
}
} inline void solve(){
int da=getdeep(A),db=getdeep(B);
if(da<db) swap(da,db),swap(A,B);
if(da>db) A=getnode(A,da-db); ans=da-db; if(!(A!=B)) return; for(int i=log(db)/log(2)+1;i>=0;i--) if((1<<i)<=db){
node AA=getnode(A,1<<i);
node BB=getnode(B,1<<i);
if(AA!=BB) A=AA,B=BB,ans+=1<<(i+1);
} ans+=2;
} int main(){
for(int i=0;i<3;i++) scanf("%d",a+i);
for(int i=0;i<3;i++) scanf("%d",b+i);
sort(a,a+3),sort(b,b+3); for(int i=2;i;i--) a[i]-=a[i-1],b[i]-=b[i-1]; A=(node){a[0],a[1],a[2]},B=(node){b[0],b[1],b[2]};
if(getroot(A)!=getroot(B)){ puts("NO"); return 0;} solve(); puts("YES");
printf("%u\n",ans); return 0;
}

  

洛谷 P1852 [国家集训队] 跳跳棋的更多相关文章

  1. 洛谷 P1852 [国家集训队]跳跳棋 解题报告

    P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...

  2. P1852 [国家集训队]跳跳棋

    P1852 [国家集训队]跳跳棋 lca+二分 详细解析见题解 对于每组跳棋,我们可以用一个三元组(x,y,z)表示 我们发现,这个三元组的转移具有唯一性,收束性 也就是说,把每个三元组当成点,以转移 ...

  3. luogu P1852 [国家集训队]跳跳棋

    luogu 直接操作是不可能的,考虑发现一些性质.可以发现如果每次跳的棋子都是两边的,那么最多只有一种方案,那么就把这样操作得到的状态记为当前状态的父亲,从一个状态这样做一定会结束.那么如果两个状态只 ...

  4. 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】

    P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...

  5. 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)

    洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...

  6. [洛谷P1527] [国家集训队]矩阵乘法

    洛谷题目链接:[国家集训队]矩阵乘法 题目背景 原 <补丁VS错误>请前往P2761 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入 ...

  7. 洛谷P1501 [国家集训队]Tree II(LCT,Splay)

    洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...

  8. 洛谷P2619 [国家集训队2]Tree I(带权二分,Kruscal,归并排序)

    洛谷题目传送门 给一个比较有逼格的名词--WQS二分/带权二分/DP凸优化(当然这题不是DP). 用来解决一种特定类型的问题: 有\(n\)个物品,选择每一个都会有相应的权值,需要求出强制选\(nee ...

  9. 洛谷 P1407 [国家集训队]稳定婚姻 解题报告

    P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...

随机推荐

  1. [hdu 2586]lca模板题(在线+离线两种版本)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 在线版本: 在线方法的思路很简单,就是倍增.一遍dfs得到每个节点的父亲,以及每个点的深度.然后 ...

  2. __cdecl,__stdcall,__fastcall,__pascal,__thiscall 的区别

    关于函数的调用规则(调用约定),大多数时候是不需要了解的,但是如果需要跨语言的编程,比如VC写的dll要delphi调用,则需要了解. microsoft的vc默认的是__cdecl方式,而windo ...

  3. 转:java 帐号激活与忘记密码 实例

    原文链接:http://endual.iteye.com/blog/1613679 一.帐户激活   在 很多时候,在某些网站注册一个用户之后,网站会给这个用户注册时填写的email地址发送一封帐户激 ...

  4. 转: 构建基于Nginx的文件服务器思路与实现

    在Web项目中使用独立的服务器来保存文件和图片的好处很多,如:便于统一管理,分流web服务器的压力,可进行访问加速等.另外当web服务器需要做集群进行负载均衡时,图片和文件上传在各个服务器之间同步将是 ...

  5. CodeMirror编辑器文本框Textarea代码高亮插件,CodeMirror的简单实用例子

    CodeMirror是一个用于编辑器文本框textarea代码高亮javascript插件,为各种编程语言实现关键字,函数,变量等代码高亮显示,丰富的api和可扩展功能以及多个主题样式,能满足您各种项 ...

  6. poj 2406 Power Strings(kmp循环节)

    题目链接:http://poj.org/problem?id=2406 题目大意:如果n%(n-next[n])==0,则存在重复连续子串,长度为n-next[n]. 例如:      a    b  ...

  7. Emmet 也有快速生成文件头的功能

    输入下边加粗的缩写,然后Tab,就OK了http://docs.emmet.io/cheat-sheet/ html:4t <!DOCTYPE HTML PUBLIC "-//W3C/ ...

  8. Red Hat EX413 通过笔记

    最近通过了EX413考试,在这里记录一下- EX413是Red Hat RH413对应的考试,RH413主要涉及Linux主机加固内容.考试大概18题的样子,给两台虚拟机,然后按照各个题目要求进行安全 ...

  9. mongoDB支持的数据类型

    下表为MongoDB中常用的几种数据类型. 数据类型 描述 String 字符串.存储数据常用的数据类型.在 MongoDB 中,UTF-8 编码的字符串才是合法的. Integer 整型数值.用于存 ...

  10. camera摄像原理之三:色温和自动白平衡【转】

    转自:http://blog.csdn.net/ghostyu/article/details/7912863 色温的定义:将黑体从绝对零度开始加温,温度每升高一度称为1开氏度(用字母K表示),当温度 ...