zoukankan      html  css  js  c++  java
  • 2020/11/04 模拟赛 圆与圆之间的距离是不能一概而论的

    Description

    给定平面上 $n$ 个圆,这些圆之间只有包含和分离两种关系(不存在相切的情况)。 定义两个圆之间的距离是从圆 $A$ 到圆 $B$ 经过的圆弧的最小个数,但是不包括 圆 $A$ 和圆 $B$ 的圆弧。两个圆之间的路径不一定只是走直线,还可以存在绕弯 的情况。 对于上述情况,从绿色圆到橙色圆的距离是 $0$,而从红色圆到橙色圆的距离是 $1$。 给出 $q$ 个询问,每个询问的格式形如 $u,v$,对于每个询问,都需要回答第 $u$ 个 圆到第 $v$ 个圆之间的最短距离。

    Solution

    题中给出数个不相交或相切的圆,问从一个圆到另一个圆最少走过几个圆

    可以想到圆的包含和相离可以视为树上的结构:圆A包含圆B就是A是B的父节点,圆A与圆B相离就是A,B为兄弟节点,那么两圆之间距离就可以用
    LCA求出

    用扫描线维护每个圆的左端点和右端点,当扫到一个入点时判断它上方的圆弧,如果是下半弧则与该圆相离,如果是上半弧则被该圆包含,那么就可以把深度和父节点更新

    最后倍增求LCA,要分LCA是否与两个圆重合两类讨论答案(果然不能一概而论)

    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<set>
    using namespace std;
    int n,q,X[100005],Y[100005],R[100005],tot,nowx,dep[100005],fa[100005],f[100005][20];
    struct Eve
    {
        double x;
        int id,typ;
        bool operator < (const Eve &z)const
        {
            return x<z.x;
        }
    }eve[200005];
    vector<int>ve[100005];
    struct Node
    {
        int id,typ;
        double loc()const
        {
            double temp=sqrt(1.0*R[this->id]*R[this->id]-1.0*(X[this->id]-nowx)*(X[this->id]-nowx)+1e-8);
            return (this->typ==1)?Y[this->id]-temp:Y[this->id]+temp;
        }
    };
    bool operator < (Node y,Node z)
    {
        return y.loc()<z.loc();
    }
    set<Node>s;
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    void dfs(int k)
    {
        f[k][0]=fa[k];
        for(int i=1;i<=19;i++) f[k][i]=f[f[k][i-1]][i-1];
        for(int v:ve[k]) dfs(v);
    }
    int lca(int u,int v)
    {
        if(dep[u]<dep[v]) swap(u,v);
        for(int i=19;~i;i--) if(dep[f[u][i]]>=dep[v]) u=f[u][i];
        if(u==v) return u;
        for(int i=19;~i;i--) if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
        return f[u][0];
    }
    int dis(int u,int v)
    {
        if(u==v) return 0;
        int d=lca(u,v);
        return (u!=d&&v!=d)?dep[u]+dep[v]-2*dep[d]-2:dep[u]+dep[v]-2*dep[d]-1;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++) X[i]=read(),Y[i]=read(),R[i]=read();
        for(int i=1;i<=n;i++) eve[++tot]=(Eve){X[i]-R[i]+1e-8,i,1},eve[++tot]=(Eve){X[i]+R[i]-1e-8,i,-1};
        sort(eve+1,eve+tot+1);
        for(int i=1;i<=tot;i++)
        {
            nowx=eve[i].x;
            if(eve[i].typ==-1) s.erase((Node){eve[i].id,1}),s.erase((Node){eve[i].id,2});
            else
            {
                auto temp=s.upper_bound((Node){eve[i].id,1});
                if(temp==s.end()) dep[eve[i].id]=1;
                else
                {
                    Node a=*temp;
                    if(a.typ==1) dep[eve[i].id]=dep[a.id],fa[eve[i].id]=fa[a.id];
                    else dep[eve[i].id]=dep[a.id]+1,fa[eve[i].id]=a.id;
                }
                s.insert((Node){eve[i].id,1}),s.insert((Node){eve[i].id,2});
            }
        }
        for(int i=1;i<=n;i++) ve[fa[i]].push_back(i);
        dfs(0);
        q=read();
        for(int i=1;i<=q;i++)
        {
            int u=read(),v=read();
            printf("%d
    ",dis(u,v));
        }
        return 0;
    }
    圆与圆之间的距离是不能一概而论的
  • 相关阅读:
    不可小视视图对效率的影响力
    Maximum Margin Planning
    PhysicsBased Boiling Simulation

    Learning Behavior Styles with Inverse Reinforcement Learning
    Simulating Biped Behaviors from Human Motion Data
    Nearoptimal Character Animation with Continuous Control
    Apprenticeship Learning via Inverse Reinforcement Learning
    回报函数学习的学徒学习综述
    Enabling Realtime Physics Simulation in Future Interactive Entertainment
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14003251.html
Copyright © 2011-2022 走看看