题目:

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. Rxjava observeOn()和subscribeOn()初探

    Rxjava这么强大的类库怎么可能没有多线程切换呢? 其中observeOn()与subscribeOn()就是实现这样的作用的.本文主要讲解observeOn()与subscribeOn()的用法, ...

  2. angular实现的按钮提示

    用angularJS简单实现了一个小的按钮提示,html文件中需要引入jquery.js和angular.js css代码: <style type="text/css"&g ...

  3. 教你怎么把iconfont转换成png透明图片

    1.进入iconfont图标库,登陆.http://www.iconfont.cn/ 2.选择想要的图标加入购物车. 3.直接选中下载图标为png格式.

  4. DRBD+Heartbeat+Mysql高可用读写分离架构

    声明:本案例仅为评估测试版本 注意:所有服务器之间必须做好时间同步 架构拓扑 IP信息: Heartbeat安装部署 1.安装heartbeat(主备节点同时安装) [root@master1 ~]# ...

  5. 关于 IDEA 自动识别问题,jsp页面Controller路径自动识别的问题

    idea之所以强大,就是强大的代码提示和联想功能,写起代码来简直不要太爽.但是这几天我发现在我的jsp页面中访问controller路径的时候不会自动提示了,对于这么严谨的我肯定要找出原因啊,哈哈. ...

  6. 抓包工具 - HttpWatch

    HttpWatch是功能强大的网页数据分析工具,集成在IE工具栏,主要功能有网页摘要.cookies管理.缓存管理.消息头发送/接收,字符查询.POST数据.目录管理功能和报告输出.HttpWatch ...

  7. std::cin>>

    cin>> 不吃最后的回车换行,字符串自动补'\0'与最后回车换行无关 时常忘记,紧记!

  8. */美女镇楼/*>>>---PHP中的OOP-->面对过程与面对对象基础概念与内容--(封装、继承、多态)

      前  言  OOP  学习了好久的PHP,今天来总结一下PHP中的重要成员OOP 1  面向过程&面向对象 1.专注于解决一个问题的过程.面向过程的最大特点,是由一个一个的函数去解决处理这 ...

  9. mysql revise

    DATABASE create database db_name; use db_name; alter database db_name; drop database db_name; show d ...

  10. WAF指纹探测及识别技术

    Web应用防护系统(也称:网站应用级入侵防御系统.英文:Web Application Firewall,简称: WAF).利用国际上公认的一种说法:Web应用防火墙是通过执行一系列针对HTTP/HT ...