2144: 跳跳棋

来源:互联网 发布:取数组的最后一个元素 编辑:程序博客网 时间:2024/09/21 08:59

跪跪跪跪跪跪。

二分+LCA什么的根本想不出来啊。

只好翻题解了。

大概就是每一个状态有两种决策。

两边的往中间跳。

中间的往两边跳。

第一种对应树上的两个儿子。

第一种对应树上的父亲。

然后就是二叉树了。

就可以倍增/二分了。

然后就乱搞出来了。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf=1e9;struct data{int p[3];};int s[3],t[3];int dis;data up(int *now,int k){data ans;int t1=now[1]-now[0],t2=now[2]-now[1];for(int i=0;i<3;i++)ans.p[i]=now[i];if(t1==t2)return ans;if(t1<t2){int tmp=min(k,(t2-1)/t1);k-=tmp;dis+=tmp;ans.p[0]+=t1*tmp;ans.p[1]+=t1*tmp;}else{int tmp=min(k,(t1-1)/t2);k-=tmp;dis+=tmp;ans.p[1]-=t2*tmp;ans.p[2]-=t2*tmp;}if(k)return up(ans.p,k);else return ans;}bool operator!=(data a,data b){for(int i=0;i<3;i++)if(a.p[i]!=b.p[i])return true;return false;}int main(){scanf("%d%d%d%d%d%d",&s[0],&s[1],&s[2],&t[0],&t[1],&t[2]);sort(s,s+3);sort(t,t+3);data t1=up(s,inf);int d1=dis;dis=0;data t2=up(t,inf);int d2=dis;dis=0;if(t1!=t2){printf("NO");return 0;}printf("YES\n");if(d1>d2){swap(d1,d2);for(int i=0;i<3;i++)swap(s[i],t[i]);}int ans=d2-d1;t1=up(t,ans);for(int i=0;i<3;i++)t[i]=t1.p[i];int l=0,r=d1;while(l<=r){int m=l+r>>1;if(up(s,m)!=up(t,m))l=m+1;else r=m-1;}printf("%d",ans+2*l);return 0;}


0 0