题意:
在X轴上有三个棋子,棋子只能隔着一个棋子跳; 就像跳棋 . 给三个棋子的初始位置和最终位置 ,问从初始位置到最终位置 棋子跳的最少步数。
分析:
首先,我们把3个数排好序。设三个数从小到大是a, b, c
设:s1=b-a s2=c-b
那么b可以跳动到a左边,或者c右边。
如果s1<s2,那么a可以跳到bc中间
如果s1>s2,那么c可以跳到ab中间
也就是说,如果s1≠s2,那么一个局面有3种跳法。
如果s1=s2,那么只有2种跳法。
如果我们用图来表示状态之间的关系,就很容易发现,状态之间组成的联
系实际上是二叉树组成的森林。
每一个s1=s2的状态都是一棵二叉树的根。
其余的每个状态,a或c往中间跳表示往父亲节点走一步
对于所有状态,中间节点往左右跳分别对应往左右孩子走一步。
原问题转换成了树上最短路问题。我们设起始状态对应节点p,目标状态对
应节点q。那么问题是:1.p和q是否同根。 2.如果同根,求p到q的距离。
这两个问题都可以用LCA的知识来解决。(LCA最近公共祖先)
参考博客:
https://blog.csdn.net/u010126535/article/details/41174729
https://blog.csdn.net/SwustLpf/article/details/84852237
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
ll a,b,c,len;
node(ll a=0,ll b=0,ll c=0,ll len=0):a(a),b(b),c(c),len(len){}
void output(){
cout<<a<<" "<<b<<" "<<c<<endl;
}
};
node solve(node &t){
ll &a=t.a,&b=t.b,&c=t.c,&cnt=t.len;
if(a>b) swap(a,b);
if(a>c) swap(a,c);
if(b>c) swap(b,c);
ll s1=b-a,s2=c-b;
while(s1!=s2){
ll tmp;
if(s1>s2){
tmp=((s1-1)/s2);
b-=tmp*s2;
c-=tmp*s2;
}else {
tmp=((s2-1)/s1);
a+=tmp*s1;
b+=tmp*s1;
}
cnt+=tmp;
s1=b-a,s2=c-b;
}
return t;
}
bool _equal(node x,node y){
if(x.a==y.a&&x.b==y.b&&x.c==y.c) return 1;
return 0;
}
node get_pre(node t,ll len){
ll &a=t.a,&b=t.b,&c=t.c;
if(a>b) swap(a,b);
if(a>c) swap(a,c);
if(b>c) swap(b,c);
ll s1=b-a,s2=c-b;
while(len>0){
ll tmp;
if(s1>s2){
tmp=((s1-1)/s2);
tmp=min(tmp,len);
b-=tmp*s2;
c-=tmp*s2;
}else {
tmp=((s2-1)/s1);
tmp=min(tmp,len);
a+=tmp*s1;
b+=tmp*s1;
}
len-=tmp;
s1=b-a,s2=c-b;
}
return t;
}
int main(){
ll a,b,c,x,y,z;
while(scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&x,&y,&z)!=EOF){
node t1(a,b,c);
node t2(x,y,z);
if(!_equal(solve(t1),solve(t2))){
printf("NO\n");
}else{
printf("YES\n");
ll len=t1.len>t2.len?t1.len-t2.len:t2.len-t1.len;
t1.a=a,t1.b=b,t1.c=c;
t2.a=x,t2.b=y,t2.c=z;
if(t1.len>t2.len){
t1=get_pre(t1,len);
}else if(t2.len>t1.len){
t2=get_pre(t2,len);
}
ll l=-1,r=(t1.len>t2.len?t2.len:t1.len)+1;
while(l+1<r){
ll mid=l+r>>1;
if(_equal(get_pre(t1,mid),get_pre(t2,mid))){
r=mid;
}else l=mid;
}
printf("%lld\n",2*r+len);
}
}
return 0;
}
/*
2 3 7
4 7 9
2 3 7
5 8 9
4 7 9
5 7 8
*/