[9018_1563][bzoj_2144]跳跳棋
题目描述
Hzwer的跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。
某一天,黄金大神和cjy用跳跳棋来做一个简单的游戏:棋盘上有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
最近公共祖先
对于一个状态,例如2 3 7
中间可以往两侧跳,即2 3 7->1 2 7 / 2 3 7->2 7 11
两侧仅有靠近中间的能往中间跳,即2 3 7->3 4 7
那么所有的状态就能表示为一棵二叉树,第一种情况为其两个儿子,第二种为其父亲
但其实第一种情况并不重要,因为lca是一直找父亲,显然,根节点的三个棋是一个等差数列
问题转换为给定树上的两个结点,求其距离。如果两个节点
我们发现若记前两个数差t1,后两个数差t2,不妨设t1<t2
则左边最多往中间跳(t2-1)/t1次
然后只能右边往中间跳,是一个辗转相除的过程,即在logK的时间内我们可以用这种方法得到某个结点它向上K次后的结点,或者根节点,同时还可以顺便算下深度
很明显,如果初始情况和最终情况的根节点不一样,那么一定无解
那么只要求始终两个状态的深度d1,d2,将较深的调整到同一深度
然后二分/倍增求与lca的深度差x
ans=2*x+abs(d1-d2)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct xxx{
int c[];
}a,b;
int dep;
xxx zou(xxx aa,int x)
{
xxx xx;
int t1=aa.c[]-aa.c[],t2=aa.c[]-aa.c[];
if(t1==t2)return aa;
if(t1<t2)
{
int yy=min(x,(t2-)/t1);dep+=yy;x-=yy;
xx.c[]=aa.c[]+yy*t1;xx.c[]=aa.c[]+yy*t1;xx.c[]=aa.c[];
}
if(t1>t2)
{
int yy=min(x,(t1-)/t2);dep+=yy;x-=yy;
xx.c[]=aa.c[];xx.c[]=aa.c[]-yy*t2;xx.c[]=aa.c[]-yy*t2;
}
if(!x)return xx;
else return zou(xx,x);
}
bool bj(xxx a,xxx b)
{
for(int i=;i<=;i++)if(a.c[i]!=b.c[i])return ;
return ;
}
int main()
{
int ans=;
for(int i=;i<=;i++)scanf("%d",&a.c[i]);
for(int i=;i<=;i++)scanf("%d",&b.c[i]);
sort(a.c+,a.c+);sort(b.c+,b.c+);
xxx xx1=zou(a,);int dep1=dep;dep=;
xxx xx2=zou(b,);int dep2=dep;dep=;
if(!bj(xx1,xx2)){puts("NO");return ;}
if(dep1>dep2){ans+=dep1-dep2;a=zou(a,dep1-dep2);dep1=dep2;}
if(dep1<dep2){ans+=dep2-dep1;b=zou(b,dep2-dep1);dep2=dep1;}
int l=,r=dep1+;
while(l<r)
{
int mid=(l+r)>>;
if(bj(zou(a,mid),zou(b,mid)))r=mid;
else l=mid+;
}
puts("YES");
printf("%d",ans+*l);
return ;
}
[9018_1563][bzoj_2144]跳跳棋的更多相关文章
- 跳跳棋(9018_1563)(BZOJ_2144)
题目: Hzwer的跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 某一天,黄金大神和cjy用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.他们要 ...
- 【LCA】bzoj 2144:跳跳棋
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 248 Solved: 121[Submit][Status][Discuss] ...
- bzoj2144 【国家集训队2011】跳跳棋
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
- [BZOJ 2144]跳跳棋
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
- BZOJ2144跳跳棋——LCA+二分
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的 游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- 洛谷 P1852 [国家集训队]跳跳棋 解题报告
P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...
- P1852 [国家集训队]跳跳棋
P1852 [国家集训队]跳跳棋 lca+二分 详细解析见题解 对于每组跳棋,我们可以用一个三元组(x,y,z)表示 我们发现,这个三元组的转移具有唯一性,收束性 也就是说,把每个三元组当成点,以转移 ...
- 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】
P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...
- 【BZOJ 2144】 2144: 跳跳棋 (倍增LCA)
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 642 Solved: 307 Description 跳跳棋是在一条数轴上进行的 ...
随机推荐
- 文件/etc/passwd,/etc/shadow,/etc/group
文件/etc/passwd /etc/shadow /etc/group 计算资源的使用(并不是所有的人都可以用这台计算机的) 权限:访问资源的的能力. 用户:获取资源或者权限的凭证. 用户的容器:关 ...
- SAP(ABAP):STOP,EXIT,CHECK,RETURN,REJECT,CONTINUE
Stop 命令使用该命令的程序位置INITIALIZATION, AT SELECTION-SCREEN, START-OF-SELECTION和GET 事件中处理说明1. 当在INITIALIZAT ...
- html_outputer.py
coding=UTF-8 # HTML输出器 import sys class htmlOutputer(): def __init__(self): self.data = [] def colle ...
- python re模块实现计算器
def mul_div(exp): #计算乘除 while True: ret = re.search('[\d\.]+[\*\/]-?[\d\.]+', exp) if ret: atom_exp ...
- MySQL权限管理创建帐户
权限管理 1.创建账号 # 本地账号 create user 'egon1'@'localhost' identified by '123'; # mysql -uegon1 -p123 # 远程帐号 ...
- 亲手搭建一个基于Asp.Net WebApi的项目基础框架2
本篇目的:封装一些抽象类 1::封装日志相关类 2:封装一个Service操作类 3:封装缓存操作类 4:封装其他一些常用Helper 1.1在Framework项目里面建立好相关操作类文件夹,以便于 ...
- Eclipse 工作空间(Workspace)---Eclipse教程第07课
Eclipse 工作空间(Workspace) eclipse 工作空间包含以下资源: 项目 文件 文件夹 项目启动时一般可以设置工作空间,你可以将其设置为默认工作空间,下次启动后无需再配置: 工作空 ...
- groupSum6后向遍历
http://codingbat.com/prob/p199368 public boolean groupSum6(int start, int[] nums, int target) { if( ...
- 《Cracking the Coding Interview》——第17章:普通题——题目7
2014-04-28 23:28 题目:给定一个数字,用英语把它读出来. 解法:ZOJ上有相反的题目.如果我要用中文读书来呢? 代码: // 17.7 Read an integer in Engli ...
- iOS笔记060 - 自定义控件
自定义tabBar 系统自带的tabBar不能满足需求 自己定义UITabBar 自定义一个类继承自UITabBar 实现initWithFrame和layoutSubviews方法即可. //#im ...