1.有两种跳法
①从两边往里跳 (x,y,z)->(x,2*y-x,z)或(x,y,z)->(x,2*y-z,y)
②从中间往外跳(y-x≠z-y) (x,y,z)->(2*x-y,x,z)或(x,y,z)->(x,z,2*z-y)
2.无解?都跳到不能跳了(y-x==z-y)都不一样,那肯定不行啊
3.发现从起始位置到目标位置,和从目标位置到起始位置答案是一样的。从目标位置和起始位置一起开始跳则一定会有重合的点(不然就无解了),那么重合的点再跳也一定会跳到(y-x==z-y)的情况,那么这个就很像LCA了。把离最远祖先(y-x==z-y)最远的那个点先跳到和另一个点一样的深度,再二分答案跳(因为不一定要跳到最远祖先的那个点)
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define INF 1000000000
struct Node
{
int x,y,z;
void orzcy()
{
scanf("%d%d%d",&x,&y,&z);
if(x>y){int t=x;x=y;y=t;}
if(x>z){int t=x;x=z;z=t;}
if(y>z){int t=z;z=y;y=t;}
}
}st,ed,a,b;
int l1,l2,len;
bool pd(Node A,Node B){return A.x==B.x&&A.y==B.y&&A.z==B.z;}
int Min(int A,int B){return A<B?A:B;}
Node Get(Node k,int lef)
{
int pre=0;
for(len=0;lef;len+=pre)
{
int u=k.y-k.x,v=k.z-k.y;
if(u==v)return k;
if(u<v)
{
pre=Min(lef,(v-1)/u);
lef-=pre;k.x+=pre*u;k.y+=pre*u;
}
else
{
pre=Min(lef,(u-1)/v);
lef-=pre;k.y-=pre*v;k.z-=pre*v;
}
}
return k;
}
int main()
{
st.orzcy();ed.orzcy();
a=Get(st,INF);l1=len;
b=Get(ed,INF);l2=len;
if(!pd(a,b)){puts("NO");return 0;}
if(l1<l2){Node t1=st;st=ed;ed=t1;int t2=l1;l1=l2;l2=t2;}
st=Get(st,l1-l2);
int l=0,r=l2;
while(l<=r)
{
int mid=(l+r)>>1;
if(pd(Get(st,mid),Get(ed,mid)))r=mid-1;
else l=mid+1;
}
printf("YES\n%d\n",(l<<1)+l1-l2);
return 0;
}