zoukankan      html  css  js  c++  java
  • UVALive 2218 Triathlon

    https://vjudge.net/problem/UVALive-2218

    题意:

    铁人三项比赛,每项比赛长度未定,已知每个选手每项比赛的平均速度。

    设计每项比赛的长度,让其中某个特定选手获胜。

    判断哪些选手有可能 获得冠军,并列不算

    每项比赛长度必须>0

    线性规划问题

    设比赛总长度为1,第一项长度为x,第二项长度为y,第三项长度为1-x-y

    则选手i打败选手j的条件是

    化为Ax+By+C>0,得

    对于每个选手i,都会得到n-1个半平面

    再加上x>0,y>0,1-x-y>0

    一共n+2个半平面

    如果这n+2个半平面有交,那么选手i可能获得冠军

    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    
    #define N 104
    
    using namespace std;
    
    const double eps=1e-7;
    
    struct Point 
    {
        double x,y;
        
        Point(double x=0,double y=0) : x(x),y(y) { }
        
    };
    
    typedef Point Vector;
    
    Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); }
    Vector operator - (Vector A,Vector B) { return Vector(A.x-B.x,A.y-B.y); }
    Vector operator * (Vector A,double b) { return Vector(A.x*b,A.y*b); }
    
    struct Line
    {
        Point P;
        Vector v;
        double ang;
        
        Line() {}
        Line(Point P,Vector v) :P(P),v(v) { ang=atan2(v.y,v.x); }
        
        bool operator < (Line L) const
        {
            return ang<L.ang;
        }
    };
    
    Line L[N];
    
    double Cross(Vector A,Vector B)
    {
        return A.x*B.y-A.y*B.x;
    }
    
    bool OnLeft(Line L,Point p)
    {
        return Cross(L.v,p-L.P)>0;
    }
    
    Point GetIntersection(Line a,Line b)
    {
        Vector u=a.P-b.P;
        double t=Cross(b.v,u)/Cross(a.v,b.v);
        return a.P+a.v*t;
    }
    
    bool HalfplaneIntersection(Line *L,int n)
    {
        sort(L,L+n);
        int first,last;
        Point *p=new Point[n];
        Line *q=new Line[n];
        q[first=last=0]=L[0];
        for(int i=1;i<n;++i)
        {
            while(first<last && !OnLeft(L[i],p[last-1])) last--;
            while(first<last && !OnLeft(L[i],p[first])) first++;
            q[++last]=L[i];
            if(fabs(Cross(q[last].v,q[last-1].v))<eps)
            {
                last--;
                if(OnLeft(q[last],L[i].P)) q[last]=L[i];
            }
            if(first<last) p[last-1]=GetIntersection(q[last-1],q[last]);
        }
        while(first<last && !OnLeft(q[first],p[last-1])) last--;
        return last-first>1;
    }
    
    int V[N],U[N],W[N];
    
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=0;i<n;++i) scanf("%d%d%d",&V[i],&U[i],&W[i]);
            for(int i=0;i<n;++i)
            {
                int lc=0; bool ok=true;
                double k=10000;
                for(int j=0;j<n;++j)
                    if(i!=j)
                    {
                        if(V[i]<=V[j] && U[i]<=U[j] && W[i]<=W[j]) { ok=false; break; }
                        if(V[i]>=V[j] && U[i]>=U[j] && W[i]>=W[j]) continue;
                        double a=(k/V[j]-k/W[j])-(k/V[i]-k/W[i]);
                        double b=(k/U[j]-k/W[j])-(k/U[i]-k/W[i]);
                        double c=k/W[j]-k/W[i];
                        Point P;
                        Vector v(b,-a);
                        if(fabs(a)>fabs(b)) P=Point(-c/a,0);
                        else P=Point(0,-c/b);
                        L[lc++]=Line(P,v);
                    }
                if(ok)
                {
                    L[lc++]=Line(Point(0,0),Vector(0,-1));
                    L[lc++]=Line(Point(0,0),Vector(1,0));
                    L[lc++]=Line(Point(0,1),Vector(-1,1));
                    if(!HalfplaneIntersection(L,lc)) ok=false;
                }
                puts(ok ? "Yes" : "No");
            }
        }
    }
  • 相关阅读:
    rwkj 1337
    poj 1002
    map
    vector
    sort排序
    sort函数
    poj 2945
    poj2388
    rwkj 1422搜索(素数环)
    poj2503
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8259831.html
Copyright © 2011-2022 走看看