P1852 [国家集训队]跳跳棋

题目背景

原《奇怪的字符串》请前往 P2543

题目描述

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

我们用跳跳棋来做一个简单的游戏:棋盘上有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


Solution

然而并不想写solution....

是一道建模题,谁能想到这道题和树可以扯上关系????

把起点和终点状态拟成树上的两个节点,就像树上求链的长度一样找lca并且把两个节点到lca的距离加起来得到答案。

听起来好玄乎??

更玄乎的是这种找lca的方法和倍增惊人地相似!

想要找到中间作为lca的转折状态,一步一步跳显然不行。由此观察题目本身的性质,给出的三个棋子是完全相同的,那么把一个作为中轴跳相当于把这两个棋子一起平移他们之间的距离。

这样可以快速地找到某一状态一直跳到不能跳时每个棋子的位置。所以首先判断如果给出的两个状态的最终状态不相同,那么输出‘NO’

所以我们还发现,两种状态跳到他们最终状态的步数的差就是它们‘深度’的差,就像倍增求lca先要把深度调成一样再一起往上跳。

所以先处理出以上需要的东西,有点像辗转相除??每次都尽量跳到不能跳,然后交换继续跳。

将两个状态深度调到一样后,一起向上跳的步数就可以用二分,每次check往上跳看是否跳到一样。

二分出的答案要乘2(链)加上深度调到一样的答案即可。

Code

#include<bits/stdc++.h>
#define LL long long
using namespace std; LL dep1, dep2, a, b, c, x, y, z, ans; LL get_root(LL a, LL b, LL c, LL &dep, LL &l) {
LL d1 = b - a, d2 = c - b;
while(d1 != d2) {
if(d2 > d1) {
LL s = d2 / d1, dis = d2 % d1;
if(!dis) {
dep += s - ;
l = d1; return a + (s - ) * d1;
}
dep += s; a += s * d1; b += s * d1;
d2 = dis;
} else {
LL s = d1 / d2, dis = d1 % d2;
if(!dis) {
dep += s - ;
l = d2; return a;
}
dep += s; b -= s * d2; c -= s * d2;
d1 = dis;
}
}
dep = ; l = d1; return a;
} void Swap(LL &a, LL &b, LL &c) {
if(a > b) swap(a, b);
if(a > c) swap(a, c);
if(b > c) swap(b, c);
} void find_fa(LL &a, LL &b, LL &c, LL step) {
while(step) {
LL d1 = b - a, d2 = c - b;
if(d2 > d1) {
LL s = d2 / d1;
if(s >= step) {
a += step * d1; b += step * d1;
return ;
}
a += s * d1; b += s * d1; step -= s;
} else {
LL s = d1 / d2;
if(s >= step) {
c -= step * d2; b -= step * d2;
return ;
}
c -= s * d2; b -= s * d2; step -= s;
}
}
} void solve() {
LL l = , r = min(dep2, dep1);
LL st;
while(l <= r) {
LL mid = (l + r) >> ;
LL aa = a, bb = b, cc = c;
LL xx = x, yy = y, zz = z;
find_fa(aa, bb, cc, mid);
find_fa(xx, yy, zz, mid);
if(aa == xx && bb == yy && cc == zz) st = mid, r = mid - ;
else l = mid + ;
}
printf("%lld", ans + st * );
} int main() {
scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &x, &y, &z);
Swap(a, b, c); Swap(x, y, z);
LL del1, del2;
LL pos1 = get_root(a, b, c, dep1, del1);
LL pos2 = get_root(x, y, z, dep2, del2);
if(del1 != del2 || pos1 != pos2) {
puts("NO"); return ;
}
puts("YES");
if(dep1 > dep2) {
ans += dep1 - dep2;
find_fa(a, b, c, dep1 - dep2);
} else if(dep2 > dep1) {
ans += dep2 - dep1;
find_fa(x, y, z, dep2 - dep1);
}
solve();
}

【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】的更多相关文章

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

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

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

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

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

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

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

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

  5. 洛谷 3379 最近公共祖先(LCA 倍增)

    洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...

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

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

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

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

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

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

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

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

随机推荐

  1. DRM学习总结(1)--- DRM框架介绍

    一.DRM 简介 In computing, the Direct Rendering Manager (DRM), a subsystem of the Linux kernel, interfac ...

  2. haproxy代理https配置方法【转】

    记得在之前的一篇文章中介绍了nginx反向代理https的方法,今天这里介绍下haproxy代理https的方法: haproxy代理https有两种方式:1)haproxy服务器本身提供ssl证书, ...

  3. asp.net操作word 配置在IIS上出现的问题

    异常: 检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问. (异常来自 ...

  4. Linux下配置Samba服务器全过程

    Linux下配置Samba服务器全过程 user级别的samba的配置 http://www.linuxidc.com/Linux/2014-11/109234.htm http://www.linu ...

  5. java基础36 双例集合Map下的HashMap和TreeMap集合

    单例集合体系: ---------| collection  单例集合的根接口--------------| List  如果实现了list接口的集合类,具备的特点:有序,可重复       注:集合 ...

  6. 工具类DateHandler

    package com.ctid.rachel.core.util; import java.math.BigDecimal;import java.util.Calendar;import java ...

  7. NOIP2015 D2T3 运输计划

    拿到题目的第一眼 首先这是一棵n个节点的树(别说你看不出来) 然后对于树上的m条链我们可以选取树上的唯一一条边使它的边权变为0 求处理后最长链的长度 20分 m=1好啦,好像可做一眼望去全是水 只需求 ...

  8. AARRR:数据运营模型

    一.基础知识 产品经理  <增长黑客>数据分析基础 -- 获取(Acquisition)-- 激活(Activation)-- 留存(Retention)-- 收入(Revenue)-- ...

  9. WDK10+VS2015 驱动环境搭建

    其实做驱动或者说底层安全的最大问题就是没有合适的资料去参考,网上很难找到想要的信息.比如搭建驱动环境我以前一直用的都是WDK7.1基于控制台去编译的,之前尝试过搭建WDK10+VS2015的组合环境, ...

  10. RabbitMQ系列之RabbitMQ集群

    本文的集群是RabbitMq 自身的Cluster搭建 . #hosts准备: vim /etc/hosts #172.16.3.79 s1 #172.16.3.105 s2 172.16.2.10 ...