跳跳棋(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 跳跳棋是在一条数轴上进行的 ...
随机推荐
- 开涛spring3(9.3) - Spring的事务 之 9.3 编程式事务
9.3 编程式事务 9.3.1 编程式事务概述 所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理. Spring框架提供一致的事务抽象,因此对于JDBC还是JTA事务都是 ...
- 项目管理之 Git 管理软件 SourceTree for Mac
Git 项目管理: Mac Terminal 生成 Git 秘钥流程: git config --global user.name "yourname" git config -- ...
- WebSocket+MSE——HTML5 直播技术解析
作者 | 刘博(又拍云多媒体开发工程师) 当前为了满足比较火热的移动 Web 端直播需求,一系列的 HTML5 直播技术迅速的发展起来. 常见的可用于 HTML5 的直播技术有 HLS.WebSock ...
- 网络安全——一图看懂HTTPS建立过程
关于网络安全加密的介绍可以看之前文章: 1. 网络安全--数据的加密与签名,RSA介绍 2. Base64编码.MD5.SHA1-SHA512.HMAC(SHA1-SHA512) 3. When I ...
- 提升单元测试体验的利器--Mockito使用总结
为神马要使用Mockito? 在编写单元测试的时候,为了尽可能的保证隔离性,我们时常需要对某些不容易构造或者不容易获取或者对外部环境有依赖的对象,用一个虚拟的对象来创建以便于测试.假设你正在开发的的代 ...
- Gradle入门学习---认识buildeTypes和dependencies
Gradle是Android Studio默认的构建工具,如果是基本的APP开发,不会涉及到Gradle太多内容,毕竟它的诞生就不是专为Android服务的. 日常开发需要涉及到使用Gradle的场景 ...
- 前端css要加的一些
编码格式 @charset "utf-8"; body的外边距设置 margin:0; 标签设置 form,ul,ol,li设置为padding:0; ul,ol,li设置为lis ...
- nodeJS实战:自定义模块与引入,不同模块的函数传递及回调处理,exports与module.exports(基于nodejs6.2.0)
前言:本文基于上一篇文章中的源代码进行改写,地址:http://blog.csdn.net/eguid_1/article/details/52182386 注意:为什么不用module.export ...
- Navicat11全系列激活(注册机)
Navicat是一款数据库管理工具, 用于简化, 开发和管理MySQL, SQL Server, SQLite, Oracle 和 PostgreSQL 的数据库: Navicat数据模型工具以图形化 ...
- CSS 简单了解(二)
我们第一天说了简单的HTML,第二天说了简单的CSS.那么今天.咱们就来说一说他们的结合如何使用吧! 首先说引用方式,和使用方法吧! 1.内部样式表.(放入<head>中) <hea ...