Problem
有三个棋子在一个一条数轴上,可以使其中一枚为轴,另一枚跳过去,但跳的过程中不能越过第三枚棋子。
给定初始状态,问能否达到最终状态,如果可以最少需要几步
Solution
首先先判断可不可以。
我们可以讲初末状态都转变成不能再走的状态,显然对于每种情况这种状态只有一个。
那如果不能再继续的状态一样,说明他们肯定是可以通过变换得到的;反之,最终状态都不同,显然不能跳出来…
这样我们记录下状态、跳的步数。
类似
l
c
a
lca
lca 的操作,看跳这么多步是否可以使结果一样
Code
#include <cstdio>
#include <algorithm>
using namespace std;
#define inf 1000000000
int tmp,a[5],b[5];
struct node{int a[5];};
node calc(int *a,int k){
node ans;
int t1=a[2]-a[1],t2=a[3]-a[2];
for(int i=1;i<=3;i++) ans.a[i]=a[i];
if(t1==t2) return ans;
if(t1<t2){
int t=min(k,(t2-1)/t1);
k-=t;tmp+=t;
ans.a[2]+=t*t1;ans.a[1]+=t*t1;
}else{
int t=min(k,(t1-1)/t2);
k-=t;tmp+=t;
ans.a[2]-=t*t2;ans.a[3]-=t*t2;
}
if(k) return calc(ans.a,k);
return ans;
}
bool operator !=(node a,node b){
for(int i=1;i<=3;i++)
if(a.a[i]!=b.a[i]) return 1;
return 0;
}
int main(){
for(int i=1;i<=3;i++) scanf("%d",&a[i]);
sort(a+1,a+4);
for(int i=1;i<=3;i++) scanf("%d",&b[i]);
sort(b+1,b+4);
tmp=0;node t1=calc(a,inf);int d1=tmp;
tmp=0;node t2=calc(b,inf);int d2=tmp;
if(t1!=t2){puts("NO");return 0;}
if(d2<d1){
swap(d1,d2);
for(int i=1;i<=3;i++) swap(a[i],b[i]);
}
int ans=d2-d1;
t1=calc(b,ans);
for(int i=1;i<=3;i++) b[i]=t1.a[i];
int l=0,r=d1,cnt=0;
while(l<=r){
int mid=l+r>>1;
if(calc(a,mid)!=calc(b,mid)) l=mid+1;
else r=mid-1,cnt=mid;
}
printf("YES\n%d\n",ans+2*cnt);
return 0;
}