【题解】P1852 跳跳棋
题意
跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。棋盘上有3颗棋子,分别在 \(a,b,c\) 这三个位置。我们要通过最少的跳动把他们的位置移动成 \(x,y,z\) 。(棋子是没有区别的)
跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过1颗棋子。
判断是否可以完成任务。如果可以,输出最少需要的跳动次数。
思路
神仙题……非常巧妙地建模。只能说:女少口阿
首先,对于中轴棋子为 \(b\) (中间那个)的情况,显然一直往中间跳可以一直减小范围,直到不能跳为止。这时候就得到了一个非常有用的“Basic” 状态,也就是“根状态”(这怎么跟某道字符串手玩题这么像啊)
然后把 \(b\) 往左右跳的情况看成左右节点状态,那么所有状态构成了一棵二叉树。对于棋盘上所有的 \(a,b,c\) ,状态构成了一个森林。
那么,如果 \((a,b,c)\to (x,y,z)\) ,首要条件是在同一棵树上。这样第一问就解决了。
考虑状态怎么去树根。利用 LCA 的思想,把两个状态到根的距离调整到一样,然后二分向上的步数,最后找到一个 \(L\) 使得两个状态向上 \(L\) 步相遇,那么总答案就是 高度差加上二分答案的两倍。
代码
#include <bits/stdc++.h>
using namespace std;
const int inf=1e9+7;
int sx,sy,sz,dep,mx;
void init( int &x,int &y,int &z )
{
x+=inf; y+=inf; z+=inf;
if ( y>z ) swap( y,z );
if ( x>y ) swap( x,y );
if ( y>z ) swap( y,z );
}
void dfs( int x,int y,int z,int step )
{
int del1=y-x,del2=z-y;
if ( step==mx || del1==del2 ) { sx=x,sy=y,sz=z; dep=step; return; }
if ( del1>del2 )
{
swap( del1,del2 ); int del=del2/del1;
if ( del2%del1==0 ) del--;
if ( step+del<=mx ) dfs( x,y-del*del1,z-del*del1,step+del );
else dfs( x,y-(mx-step)*del1,z-(mx-step)*del1,mx );
}
else
{
int del=del2/del1; del-=(del2%del1==0);
if ( step+del<=mx ) dfs( x+del*del1,y+del*del1,z,step+del );
else dfs( x+(mx-step)*del1,y+(mx-step)*del1,z,mx );
}
}
int main()
{
int x,y,z,a,b,c;
scanf( "%d%d%d",&a,&b,&c ); init( a,b,c );
scanf( "%d%d%d",&x,&y,&z ); init( x,y,z );
mx=inf;
dfs( a,b,c,0 ); int sa=sx,sb=sy,sc=sz,sd=dep;
dfs( x,y,z,0 );
if ( sx!=sa || sy!=sb || sz!=sc ) { printf( "NO" ); return 0; }
printf( "YES\n" );
//------------query1-------------------
int ans=0;
if ( sd>dep )
{
ans=sd-dep; mx=sd-dep;
dfs( a,b,c,0 ); a=sx; b=sy; c=sz;
}
if ( sd<dep )
{
ans=dep-sd; mx=dep-sd;
dfs( x,y,z,0 ); x=sx,y=sy,z=sz;
}
int l=0,r=inf;
while ( l<=r )
{
mx=(l+r)>>1;
dfs( a,b,c,0 ); sa=sx,sb=sy,sc=sz;
dfs( x,y,z,0 );
if ( sa!=sx || sb!=sy || sc!=sz ) l=mx+1;
else r=mx-1;
}
printf( "%d",(l<<1)+ans );
}
【题解】P1852 跳跳棋的更多相关文章
- P1852 跳跳棋 [LCA思想+二分答案]
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有\(3\)颗棋子,分别在\(a,b,c\)这三个位置.我们要通过最少的跳动 ...
- [luogu]P1852跳跳棋
题目重点是每次不能跳过两个棋子 即对于每一个棋子的状态(a,b,c) (a<b<c) 最多有两种移动的方式 1.中间往两边跳 (a,b,c)-->(2b-a,a,c)或(a,c,2b ...
- P1852 [国家集训队]跳跳棋
P1852 [国家集训队]跳跳棋 lca+二分 详细解析见题解 对于每组跳棋,我们可以用一个三元组(x,y,z)表示 我们发现,这个三元组的转移具有唯一性,收束性 也就是说,把每个三元组当成点,以转移 ...
- 洛谷 P1852 [国家集训队]跳跳棋 解题报告
P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...
- 洛谷 P1852 [国家集训队] 跳跳棋
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- [BZOJ 2144]跳跳棋
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
- 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】
P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...
- 【bzoj2144】跳跳棋
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 492 Solved: 244[Submit][Status][Discuss] ...
- bzoj2144 跳跳棋 二分
[bzoj2144]跳跳棋 Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位 ...
随机推荐
- C++之父:精通C++很难,但你一天之内就能学习使用C++
精通C++听起来好像就是一个笑话.为什么C++比别的语言难学那么多?其实这基本上是因为C++之父Bjarne Stroustrup 说过的一句话"我特别的讨厌语言的设计者把自己的喜好强加给用 ...
- rhel8/centos8网络网卡设置ping不通,连接不上,各种问题
[解决问题]: 1-ping不通宿主机 2-ping不通外网 3-ping不通网关 4-网络中心VMnet8 VMnet1 VMnet0 不见了 5-rhel8网络设置全攻略 环境:win10宿主机+ ...
- Ceph部署mon出现0.0.0.0地址
前言 最近在群里两次看到出现mon地址不对的问题,都是显示0.0.0.0:0地址,如下所示: [root@lab8106 ceph]# ceph -s cluster 3137d009-e41e-41 ...
- threading中的其他部分方法
import threading def wahaha(n): print(n, threading.current_thread()) # 1 <Thread(Thread-1, starte ...
- Nacos一致性算法
1. CAP原则 又称CAP定理,指的是在一个分布式系统中,一致性(Consistency).可用性(Availability).分区容错性(Partition tolerance).CAP 原则指的 ...
- [原题复现][极客大挑战 2019]BuyFlag
简介 原题复现:[极客大挑战 2019]BuyFlag 考察知识点:php函数特性(is_numeric().strcmp函数()) 线上平台:https://buuoj.cn(北京联合大学公开 ...
- tp5配置引入使用redis
1.首先你的php得是已经安装了redis扩展的 2.在tp里找到config.php配置文件,找到cache,改成下面的样子 'cache' => [ // 选择模式 'type' => ...
- 其实SQL优化调优,就跟吃饭喝水一样简单,教你抓住SQL的本质!
前言 SOL 优化并不简单,做好 SOL 优化需要掌握数据库体系结构.表和索引设计.高效 SOL法.高级 SOL 语法.多种优化工具等知识,甚至还得分析业务特点,以及了解优化器的缺点.只有建立 SOL ...
- jQuery 第二章 实例方法 DOM操作取赋值相关方法
取赋值相关方法: .html() .text() .val() .size() .addClass() .removeClass() .hasClass() .html() html方法干嘛的呢,底 ...
- 一万三千字的HashMap面试必问知识点详解
目录 概论 Hasmap 的继承关系 hashmap 的原理 解决Hash冲突的方法 开放定址法 再哈希法 链地址法 建立公共溢出区 hashmap 最终的形态 Hashmap 的返回值 HashMa ...