1 2 3 0 3 5
YES 2HintThe middle checker jumps to position 0, and the status is 0 1 3 Then , the middle one jumps to 5.
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
//向中间走类似向根节点走,向两边走类似向二叉树左右走
//y-x=z-y 树根
struct State
{
long long x,y,z,d;//x<y<z; d为到根节点的距离,初始化为0
void init()
{
d=0;
if(x>y) swap(x,y);
if(x>z) swap(x,z);
if(y>z) swap(y,z);
}
};
bool Equal(const State &a,const State &b)//不用判断d
{
if(a.x==b.x&&a.y==b.y&&a.z==b.z) return true;
return false;
}
State Root(State &a)//找a的根节点并计算出a到根节点的距离
{
State cnt=a;
long long l=cnt.y-cnt.x,r=cnt.z-cnt.y;
while(l!=r)//l=r时到树根
{
long long t;
if(l<r)//右面区间大,x、y向右走
{
if(r%l==0) t=r/l-1;
else t=r/l;
cnt.x+=t*l;
cnt.y+=t*l;
}
else
{
if(l%r==0) t=l/r-1;
else t=l/r;
cnt.z-=t*r;
cnt.y-=t*r;
}
a.d+=t;
l=cnt.y-cnt.x,r=cnt.z-cnt.y;
}
return cnt;
}
State stateUp(const State &a,long long step)//a状态向上走step步,step<=a.d
{
State cnt=a;
cnt.d=a.d-step;
long long l=cnt.y-cnt.x,r=cnt.z-cnt.y;
while(step>0)
{
long long t;
if(l<r)//右面区间大,x、y向右走
{
if(r%l==0) t=r/l-1;
else t=r/l;
if(t>step) t=step;
cnt.x+=t*l;
cnt.y+=t*l;
}
else
{
if(l%r==0) t=l/r-1;
else t=l/r;
if(t>step) t=step;
cnt.z-=t*r;
cnt.y-=t*r;
}
step-=t;
l=cnt.y-cnt.x,r=cnt.z-cnt.y;
}
return cnt;
}
int main()
{
State st,ed;
while(scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&st.x,&st.y,&st.z,&ed.x,&ed.y,&ed.z)==6)
{
st.init();ed.init();//初始化
State stRoot=Root(st);
State edRoot=Root(ed);
//st和ed根不相同
if(!Equal(stRoot,edRoot))
{
printf("NO\n");
continue;
}
//st和ed根相同
//二分答案查找st和ed的最近公共祖先
//首先把两初始状态调整到一个深度
long long res=st.d-ed.d>0?st.d-ed.d:ed.d-st.d;
if(st.d>ed.d) st=stateUp(st,res);
else ed=stateUp(ed,res);
//二分答案
long long l=0,r=st.d;
while(l<r)
{
long long mid=(l+r)/2;
if(Equal(stateUp(st,mid),stateUp(ed,mid))) r=mid;
else l=mid+1;
}
printf("YES\n%I64d\n",res+2*r);//answer=res+2*r
}
return 0;
}