题目:

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

某一天,黄金大神和cjy用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置。他们要通过最少的跳动把它们的位置移动成x,y,z。(棋子是没有区别的)

跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过1颗棋子。

写一个程序,首先判断是否可以完成任务。如果可以,输出最少需要的跳动次数。

  这道题的状态是可以在树上处理的,对于一个中间到两端距离不等的点,我们把中间的点向左跳作为它的左子树,向右跳作为右子树,同理,一个节点的父亲就是距中间点较近的点向另一边跳,显然,当且仅当两状态所属的节点有公共祖先时题目有解,输出步数只需要跑lca将目标节点和初始节点到根的距离减去最近公共祖先到根的距离的两倍即可。实现中注意用gcd来处理向上追溯的过程。

#include <cstdio>
#include <cstring>
#define swap(a,b) swaps=a,a=b,b=swaps;
#define lcas(a,b,c,g) gcdlca(b-a>c-b?b-a:c-b,b-a<=c-b?b-a:c-b,b-a>c-b?-1:1,g,a,b,c);
#define min(a,b) a<b?a:b
using namespace std;
int ansabc=,ansxyz=,ans=;
int aa,bb,cc,xx,yy,zz,swaps;
bool gcdlca(int q,int p,short int k,int g,int &x,int &y,int &z){
int r=q%p;
int l=q/p;
if(r==){
l--;
r=p;
if(k==){
if(l>=g){
y=z-r-p*(l-g);
x=z-r-p*(l-g+);
return true;
}
y=z-r;
x=y-p;
ansabc+=l;
return false;
}
else{
if(l>=g){
y=x+r+p*(l-g);
z=x+r+p*(l-g+);
return true;
}
y=x+r;
z=y+p;
ansabc+=l;
return false;
}
}
if(k==){
if(l>g){
y=z-r-p*(l-g);
x=z-r-p*(l-g+);
return true;
}
y=z-r;
x=y-p;
ansabc+=l;
gcdlca(p,r,-,g-l,x,y,z);
}
else{
if(l>g){
y=x+r+p*(l-g);
z=x+r+p*(l-g+);
return true;
}
y=x+r;
z=y+p;
ansabc+=l;
gcdlca(p,r,,g-l,x,y,z);
}
}
int lca()
{
int a2,b2,c2,x2,y2,z2,a3=aa,b3=bb,c3=cc;
int a1=a2=aa,b1=b2=bb,c1=c2=cc,x1=x2=xx,y1=y2=yy,z1=z2=zz;
lcas(x1,y1,z1,0x7fffffff);
ansxyz=ansabc; ansabc=;
lcas(a1,b1,c1,0x7fffffff);
if(!(a1==x1&&b1==y1&&c1==z1)){
printf("NO\n");
return -;
}
// printf("%d\n",ansabc);
// printf("%d\n",ansxyz);
int t;
if((ansabc-ansxyz)>)
t=ansabc-ansxyz;
else
t=ansxyz-ansabc;
ans=ansabc+ansxyz;
int ll=min(ansabc,ansxyz);
for(int i=; i<=; i++)
if((<<i)&t){
if(ansxyz>ansabc){
lcas(x2,y2,z2,<<i);
}
else lcas(a2,b2,c2,<<i);
}
a3=a2;b3=b2;c3=c2;
for(int i=; i>=; i--)
{
if(!(a2==x2&&b2==y2&&c2==z2)&&ll>=(<<i))
{
//printf("%d\n",i);
aa=a2,bb=b2,cc=c2;
xx=x2;yy=y2;zz=z2;
lcas(x2,y2,z2,<<i);
lcas(a2,b2,c2,<<i);
if(a2==x2&&b2==y2&&c2==z2){
a3=a2;b3=b2;c3=c2;
a2=aa,b2=bb,c2=cc;
x2=xx;y2=yy;z2=zz;
continue;
}
ll-=(<<i);
}
}
ansabc=;
//printf("%d\n%d\n%d\n",a3,b3,c3);
lcas(a3,b3,c3,0x7fffffff);
return ans-*ansabc;
}
void sso(int &a,int &b,int &c){
if(a>b) swap(a,b);
if(b>c) swap(b,c);
if(a>b) swap(a,b);
return ;
}
int main() {
scanf("%d%d%d%d%d%d",&aa,&bb,&cc,&xx,&yy,&zz);
sso(aa,bb,cc);
sso(xx,yy,zz);
//printf("%d%d%d%d",a,b,c,ansabc);
//printf("%d%d%d%d",x,y,z,ansxyz);
int yyyy=lca();
if(yyyy==-) return ;
else printf("YES\n%d",yyyy);
return ;
}

跳跳棋(9018_1563)(BZOJ_2144)的更多相关文章

  1. [9018_1563][bzoj_2144]跳跳棋

    题目描述 Hzwer的跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 某一天,黄金大神和cjy用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.他们 ...

  2. 【LCA】bzoj 2144:跳跳棋

    2144: 跳跳棋 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 248  Solved: 121[Submit][Status][Discuss] ...

  3. bzoj2144 【国家集训队2011】跳跳棋

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

  4. [BZOJ 2144]跳跳棋

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

  5. BZOJ2144跳跳棋——LCA+二分

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

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

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

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

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

  8. 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】

    P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...

  9. 【BZOJ 2144】 2144: 跳跳棋 (倍增LCA)

    2144: 跳跳棋 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 642  Solved: 307 Description 跳跳棋是在一条数轴上进行的 ...

随机推荐

  1. RFM模型——构建数据库营销的商业战役!(转)

    RFM模型:R(Recency)表示客户最近一次购买的时间有多远,F(Frequency)表示客户在最近一段时间内购买的次数,M (Monetary)表示客户在最近一段时间内购买的金额.一般原始数据为 ...

  2. Spring component-scan 的逻辑 、单例模式下多实例问题、事务失效

    原创内容,转发请保留:http://www.cnblogs.com/iceJava/p/6930118.html,谢谢 之前遇到该问题,今天查看了下 spring 4.x 的代码 一,先理解下 con ...

  3. Unity运动残影技能

    残影实现: 1.List<DrawMesh> list,此list中包含某一帧动画模型网格.材质 2.每过一段时间就将运动物体的模型add到list中(优化:未实现,网格合并) 3.Lat ...

  4. Html5语义化标签详解及其兼容性处理

    <header></header> 页眉 主要用于页面的头部的信息介绍,也可用于板块头部 <hgroup></hgroup> 页面上的一个标题组合 一个 ...

  5. final关键字(最终的)

    1.fianl关键字可以用来修饰类.属性.方法: 2.final关键字修饰的类不能再继承: 如:String   String类是final修饰的类不能被继承 3.final关键字修饰的方法不能被重写 ...

  6. loadrunner学习理论之一

    1.负载测试.压力测试的区别? 答:负载测试是在被测系统所承受的正常范围内进行的 压力测试可以在极端的条件下进行 2.loadrunner的三大组件是什么,有什么作用? 答:虚拟用户生成器(virtu ...

  7. 关于getHTML()方法和getHtmlAjax()方法 GetHttpLength, 清除HTML标签

    public string getHtml(string Url, string type = "UTF-8") { try { System.Net.WebRequest wRe ...

  8. mybatis if test加筛选条件

    最近在项目使用mybatis中碰到个问题 <if test="type=='y'"> and status = 0 </if> 当传入的type的值为y的时 ...

  9. 如何给两个swiper建立关系

    单个swiper已经满足不了需求了. 各种花式轮播已经慢慢进入市场.swiper该如何立足,那么请看. <div class="swiper-container"> & ...

  10. nginx是什么nginx安装与配置之windows版

    1.nginx是什么 为了快速了解nginx我们先引用网上的nginx介绍: Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP ...