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. Dream------scala--Tuple、Array、Map与文件操作

    1.Tuple(元组) 一般使用中,假设一个函数返回多个值,我们可以使用tuple接受这个(val (x,y) = myfunction) package com.wls.scala.hello /* ...

  2. weblogica 目录结构 简单介绍 创建domain domain所在目录

    1. samples 创建过程略过 domain的目录 [weblogic@node2 base_domain]$ pwd /home/weblogic/Oracle/Middleware/Oracl ...

  3. Once you eliminate all the other factors,the only thing remaining must be the truth.

    Once you eliminate all the other factors,the only thing remaining must be the truth. 一旦你排除了杂因,剩下的一定是 ...

  4. 全网最全JS正则表达式 校验数字

    Js代码 <script type="text/javascript"> function SubmitCk() { var reg = /^([a-zA-Z0-9]+ ...

  5. 你的组织使用了 windows defender 应用程序控制来阻止此应用

    =============================================== 2018/2/8_第1次修改                       ccb_warlock === ...

  6. show engine innodb status 详细介绍

    Contents Header1 SEMAPHORES. 1 LATEST DETECTED DEADLOCK. 3 TRANSACTIONS. 5 什么是purge操作... 5 FILE I/O. ...

  7. 5 个非常有用的 Laravel Blade 指令,你用过哪些?

    接下来我将带大家认识下五个 Laravel Blade 指令,这些指令将让你在解决特定问题时如虎添翼.如果你是刚接触 Laravel 的用户,这些小技巧能带你认识到 Laravel Blade 模板引 ...

  8. XShell安装

    Xshell就是一个远程控制Centos的软件:(用XShell比较方便,试用的都知道,界面也人性化) 详细介绍请看 百度百科 下面我们来安装下这个工具: 双击exe 点下一步: 选 免费的 然后下一 ...

  9. C#控制台应用程序之选课系统

    本程序以文本文件作为存储媒介,实现了一个简化版的选课系统,主要实现了以下功能 对学生信息的增删改查 对课程信息的增删改查 对学生选课的增删改查 using System; using System.C ...

  10. ASP.NET Web API 2 external logins with Facebook and Google in AngularJS app

    转载:http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-a ...