跳跳棋(9018_1563)(BZOJ_2144)
题目:
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)的更多相关文章
- [9018_1563][bzoj_2144]跳跳棋
题目描述 Hzwer的跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 某一天,黄金大神和cjy用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.他们 ...
- 【LCA】bzoj 2144:跳跳棋
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 248 Solved: 121[Submit][Status][Discuss] ...
- bzoj2144 【国家集训队2011】跳跳棋
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
- [BZOJ 2144]跳跳棋
Description 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他 ...
- BZOJ2144跳跳棋——LCA+二分
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的 游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- 洛谷 P1852 [国家集训队]跳跳棋 解题报告
P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...
- P1852 [国家集训队]跳跳棋
P1852 [国家集训队]跳跳棋 lca+二分 详细解析见题解 对于每组跳棋,我们可以用一个三元组(x,y,z)表示 我们发现,这个三元组的转移具有唯一性,收束性 也就是说,把每个三元组当成点,以转移 ...
- 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】
P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...
- 【BZOJ 2144】 2144: 跳跳棋 (倍增LCA)
2144: 跳跳棋 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 642 Solved: 307 Description 跳跳棋是在一条数轴上进行的 ...
随机推荐
- root用户不能修改iptable文件
问题: 需要放通IP 端口 执行: vi /etc/sysconfig/iptables, 添加完成后,wq保存,提示文件只读无法保存!!! 解决步骤: 1.查看文件权限 ls -ld /etc/ ...
- Libevent源码分析—event, event_base
event和event_base是libevent的两个核心结构体,分别是反应堆模式中的Event和Reactor.源码分别位于event.h和event-internal.h中 1.event: s ...
- 教你怎么把iconfont转换成png透明图片
1.进入iconfont图标库,登陆.http://www.iconfont.cn/ 2.选择想要的图标加入购物车. 3.直接选中下载图标为png格式.
- 关于QT中的音频通信问题
今天给大家讲说一个新的东西,使用QT实现音频通信的功能,挺起来是不是很高大上啊,哈哈,实际上我们只是使用一些接口做一些简单的工作而已,并不是让你写一个传输协议和采集音频信息,好了,那我们就来说一说关于 ...
- python——爬虫&问题解决&思考(三)
继续上一篇文章的内容,上一篇文章中,将爬虫调度器已经写好了,调度器是整个爬虫程序的"大脑",也可以称之为指挥中心.而现在,我们要做的就是去将调度器中用到的其他组件写好.首先是url ...
- 【webpack】webpack-dev-server生猛上手——让我们来搭一个webpack的微服务器吧!
[前言]:因为最近在搞百度地图API的时候到了webpack的externals,才发现我之前都只是用webpack做一些搭建完项目后的"收尾工作"--即打包,而没有把它纳入到 ...
- DOS学习札记(一)
DOS学习入门 最近碰到几个关于cmd命令操作,感觉操作快捷方便(也许是偶尔新鲜感使然),由于重装系统后,系统的资源管理器与功能分布都有一些不同,导致在寻找一些windows功能时有些费劲,比如说关闭 ...
- iOS CAShapeLayer、CADisplayLink 实现波浪动画效果
iOS CAShapeLayer.CADisplayLink 实现波浪动画效果 效果图 代码已上传 GitHub:https://github.com/Silence-GitHub/CoreAnima ...
- JavaScript中对事件简单的理解(2)
事件(event) event对象 (1)什么是event对象? Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态.事件通常与函数结合使用,函数不会 ...
- HTML标签类型及特点
关键词:块级元素 行级元素 行内块元素 一. 概述 HTML(Hyper Text Markup Language )作为一种标记语言,网页所有的内容均书写在标签内部,标签是 ...