• 洛谷P1852 跳跳棋


    将三颗棋子看作三元组 ((x,y,z) x<y<z),得其能转移到的状态有:

    [largeegin{aligned} &(2x-y,x,z) \ &(x,z,2z-y) \ &(x,2y-z,y) (y-x>z-y) \ &(y,2y-x,z) (y-x<z-y) \ end{aligned} ]

    后两个转移只会满足其中一个,那么将中间棋子向两边跳看作左右儿子,两边棋子向中间跳看作父亲,根节点为满足 (y-x=z-y) 的状态,那么每个状态都唯一对应一棵二叉树。

    到树上的 (lca) 即为最小步数,可以通过除来加快跳父亲的过程,然后二分找 (lca) 即可。

    #include<bits/stdc++.h>
    #define inf 1000000000
    using namespace std;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int dep;
    struct node
    {
        int x,y,z;
        void init()
        {
            read(x),read(y),read(z);
            int a[3]={x,y,z};
            sort(a,a+3),x=a[0],y=a[1],z=a[2];
        }
    }s,t;
    bool operator == (const node &a,const node &b)
    {
        return a.x==b.x&&a.y==b.y&&a.z==b.z;
    }
    node find(node p,int d,int goal)
    {
        int x=p.x,y=p.y,z=p.z,d1=y-x,d2=z-y;
        if(d==goal||d1==d2)
        {
            dep=d;
            return p;
        }
        if(d1>d2)
        {
            swap(d1,d2);
            int v=min(d2/d1-(d2%d1==0),goal-d);
            return find((node){x,y-v*d1,z-v*d1},d+v,goal);
        }
        int v=min(d2/d1-(d2%d1==0),goal-d);
        return find((node){x+v*d1,y+v*d1,z},d+v,goal);
    }
    int calc()
    {
        int d1,d2,val,l=0,r=inf,dis;
        find(s,0,inf),d1=dep,find(t,0,inf),d2=dep;
        if(d1>d2) s=find(s,0,d1-d2);
        else t=find(t,0,d2-d1);
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(find(s,0,mid)==find(t,0,mid)) dis=mid,r=mid-1;
            else l=mid+1;
        }
        return abs(d1-d2)+dis*2;
    }
    int main()
    {
        s.init(),t.init();
        if(find(s,0,inf)==find(t,0,inf)) printf("YES
    %d",calc());
        else puts("NO");
        return 0;
    }
    
  • 相关阅读:
    手指抽搐强迫症 之 APM病理分析器 v0.0.0.3 (11月24日更新)
    [转帖]修改MySql密码及访问限制设置详解
    C#学习笔记
    CodeSmith快速向导
    奇葩的maxscript
    MASM中可以定义的变量类型
    js琐记
    史上最全的css hack(ie69,firefox,chrome,opera,safari)
    逆向win32程序的思路琐记
    makefile伪目标
  • 原文地址:https://www.cnblogs.com/lhm-/p/14039218.html
Copyright © 2020-2023  润新知