题目描述

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

我们用跳跳棋来做一个简单的游戏:棋盘上有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. 【NOIP模拟赛】Evensgn 的债务 乱搞

    biubiu~~~ 我们发现按照这道题的题意我们把一个个人的前后(欠钱,被欠钱)都缩一下,那么他对其他人没有影响,那么我们就可以依次缩完每个人,而且每个人最后的状态都是要买欠要么被欠,那么我们可以知道 ...

  2. Ubuntu下安装LNMP之nginx的安装

    Nginx 最初是作为一个 Web 服务器创建的,用于解决 C10k 的问题.作为一个 Web 服务器,它可以以惊人的速度为您的数据服务.但 Nginx 不仅仅是一个 Web 服务器,你还可以将其用作 ...

  3. The 13th Zhejiang Provincial Collegiate Programming Contest - C

    Defuse the Bomb Time Limit: 2 Seconds      Memory Limit: 65536 KB The bomb is about to explode! Plea ...

  4. Codeforces Round #510 (Div. 2) D. Petya and Array(树状数组)

    D. Petya and Array 题目链接:https://codeforces.com/contest/1042/problem/D 题意: 给出n个数,问一共有多少个区间,满足区间和小于t. ...

  5. 两个神奇的函数~~~sscanf、atoi

    sscanf 对你没有看错 多了一个s 这个函数有什么作用呢 功能:读取字符串中的int.double.long.long long .float and so on 类型的数据 譬如说 我现在读入了 ...

  6. MongoDB加索引

    1.登陆MongoDB, 命令行在MongoDB主目录下执行:mongo -port 27017 2.切换至需要添加索引的db 并授权 use MeetingBooking db.auth({&quo ...

  7. Terminals Project

    https://github.com/Terminals-Origin Terminals Project Terminals is a secure, multi tab terminal serv ...

  8. WebComponents四大天王教程

    Shadow Dom: http://www.html5rocks.com/zh/tutorials/webcomponents/shadowdom/ http://www.html5rocks.co ...

  9. 【BZOJ1901】Dynamic Rankings [整体二分]

    Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定一个含 ...

  10. 【BZOJ3624】【APIO2008】免费道路 [生成树][贪心]

    免费道路 Time Limit: 2 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Input Output Sampl ...