题目:

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. (数字IC)低功耗设计入门(四)——RTL级低功耗设计

    二.RTL级低功耗设计 前面介绍了系统级的低功耗设计,换句话说就是在系统级降低功耗可以考虑的方面.系统级的低功耗设计,主要是由系统级设计.具有丰富经验的人员实现,虽然还轮不到我们设计,我们了解一下还是 ...

  2. Microsoft Azure IoTHub Serials 1 - 使用Android设备与Azure IoTHub进行交互

    Azure IoTHub的目标是为物联网的应用场景提供方便的设备接入,完成消息的发送和接收(C2D和D2C).经过持续不断的努力,目前Azure IoTHub已经支持多种操作系统设备的接入,包括And ...

  3. ActionContext、ServletContext、pageContext的区别?

    ActionContext是当前的Action的上下文环境,通过ActionContext可以获取到request.session.ServletContext等与Action有关的对象的引用: Se ...

  4. 关于ASP.NET WebForm与ASP.NET MVC的比较

      WebForm的理解 1. WebForm概念 ASP.NETWebform提供了一个类似于Winform的事件响应GUI模型(event-drivenGUI),隐藏了HTTP.HTML.Java ...

  5. 每篇半小时1天入门MongoDB——2.MongoDB环境变量配置和Shell操作

    上一篇:每篇半小时1天入门MongoDB——1.MongoDB介绍和安装 配置环境变量 Win10系统为例 右键单击“此电脑”——属性——高级系统设置——高级——环境变量,添加C:\Program F ...

  6. getElementById和querySelector方法的区别

    "querySelector 属于 W3C 中的 Selectors API 规范 .而 getElementsBy 系列则属于 W3C 的 DOM 规范" 1.区别 getXXX ...

  7. vue-router如何根据不同的用户给不同的权限

    闲聊: 小颖去年在上家公司用的vue1.0之前在做路由这块用的router.map,但是现在vue2.0里已经不能用了,所以之前解决权限问题的例子,小颖也参考不了呜呜 之前看一个美女写的:elemem ...

  8. ionic中点击图片看大图的实现

    在页面上显示了几张图片后,因为是手机端,图片会有点小的感觉,就想着怎么样才能让用户点击小图片看到大图呢,项目中ionic结合angularjs实现了这个功能 1.首先是三张小图上应添加一个函数,当点击 ...

  9. v9.5.2上传缩略图/附件提示“undefined”

    把phpcms\modules\attachment\attachments.php中将                        if(empty($this->userid)){改成  ...

  10. 愚公oracle数据库同步工具

    最近,利用一些时间对oracle数据库实时同步工具做了一些调研分析,主要关注了linkedin的databus和阿里的yugong两个中间件,其中databus需要在每个待同步的表上增加额外的列和触发 ...