洛谷 P1852 [国家集训队] 跳跳棋
题目描述
跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。
我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移动成x,y,z。(棋子是没有区别的)
跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过1颗棋子。
写一个程序,首先判断是否可以完成任务。如果可以,输出最少需要的跳动次数。
输入输出格式
输入格式:
第一行包含三个整数,表示当前棋子的位置a b c。(互不相同)
第二行包含三个整数,表示目标位置x y z。(互不相同)
输出格式:
如果无解,输出一行NO。
如果可以到达,第一行输出YES,第二行输出最少步数。
输入输出样例
1 2 3
0 3 5
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 [国家集训队] 跳跳棋的更多相关文章
- 洛谷 P1852 [国家集训队]跳跳棋 解题报告
P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...
- P1852 [国家集训队]跳跳棋
P1852 [国家集训队]跳跳棋 lca+二分 详细解析见题解 对于每组跳棋,我们可以用一个三元组(x,y,z)表示 我们发现,这个三元组的转移具有唯一性,收束性 也就是说,把每个三元组当成点,以转移 ...
- luogu P1852 [国家集训队]跳跳棋
luogu 直接操作是不可能的,考虑发现一些性质.可以发现如果每次跳的棋子都是两边的,那么最多只有一种方案,那么就把这样操作得到的状态记为当前状态的父亲,从一个状态这样做一定会结束.那么如果两个状态只 ...
- 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】
P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...
- 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)
洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...
- [洛谷P1527] [国家集训队]矩阵乘法
洛谷题目链接:[国家集训队]矩阵乘法 题目背景 原 <补丁VS错误>请前往P2761 题目描述 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. 输入输出格式 输入 ...
- 洛谷P1501 [国家集训队]Tree II(LCT,Splay)
洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...
- 洛谷P2619 [国家集训队2]Tree I(带权二分,Kruscal,归并排序)
洛谷题目传送门 给一个比较有逼格的名词--WQS二分/带权二分/DP凸优化(当然这题不是DP). 用来解决一种特定类型的问题: 有\(n\)个物品,选择每一个都会有相应的权值,需要求出强制选\(nee ...
- 洛谷 P1407 [国家集训队]稳定婚姻 解题报告
P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...
随机推荐
- 如何快速的进行sql脚本升级
sql脚本升级即从一个老的脚本升级到一个新的全量的脚本.比如公司有某一个项目,有的客户已经用这个项目了,数据库里面去掉以前的初始化数据外,现在还有了客户自己的数据.但是这个版本中有严重的bug,所以为 ...
- var result = eval('(' + data + ')');的学习
$.post("url", function(data) { //这里的function(data)这里的data是前端页面获取的后台的返回的数据: var result = ev ...
- js实现日历
有这样一个普通的日历需求 第一反应就是找插件,结果找到了,但是改起来非常麻烦,然后查下实现的原理,发现原来很简单,于是自己实现了一个. 首先分析一下这个组件,每页显示的是 当前月的所有日期及所占据的行 ...
- 我之理解---计时器setTimeout 和clearTimeout
今天在写个图片切换的问题 有动画滞后的问题,才动手去查setTimeout 和clearTimeout.之前写的图片播放器也有类似的问题,有自动start按钮 和stop按钮, 其他都正常,问题出在每 ...
- bzoj 3100 排列
题目大意: 给你长度为 \(1e6\) 的序列, 求最大的 \(K\) 使得序列中含有一个 \(K\) 的排列 做法: 性质: 区间包含1, 元素不重, 区间最大值=区间长度 枚举一个 \(1\) 让 ...
- MySQL实现分页查询
imit 基本实现方式 一般情况下,客户端通过传递 pageNo(页码).pageSize(每页条数)两个参数去分页查询数据库中的数据,在数据量较小(元组百/千级)时使用 MySQL自带的 limit ...
- GDSOI2015的某道题目
分析: 看到这个$3^i$就觉得很奇怪的样子...为什么一定要是$3^i$...而且不能重复使用... 不能重复使用就代表不会产生进位,那么一定是若干个$3^i$相加减的式子... 仔细观察,我们发现 ...
- NOIP2005过河(青蛙过河)
题目传送门 这道题主要是因为L长度最大可以为1e9 而石子却最多只有100个 这样就浪费了很多时间空间 所以我们压缩一波路径就可以了 剩余的就是枚举每个点以及i-y到i-x的dp了 这里要说一句为什么 ...
- [转]在树莓派上搭建LAMP服务
之前介绍过树莓派上LNMP环境的搭建方法,本文将详细介绍如何在树莓派上配置LAMP服务. 为LAMP,是最流行的服务器配置之一,LAMP的含义是: Linux - 操作系统 Apache - 网络服务 ...
- HDU3910(数学期望题,题目难懂)
Liang Guo Sha Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...