zoukankan      html  css  js  c++  java
  • BZOJ 1829 [Usaco2010 Mar]starc星际争霸 ——半平面交

    发现最终的结果只和$s1$,$s2$,$s3$之间的比例有关。

    所以直接令$s3=1$

    然后就变成了两个变量,然后求一次半平面交。

    对于每一个询问所属的直线,看看半平面在它的那一侧,或者相交就可以判断谁会赢比赛。

    打了个表QaQ

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define eps 1e-13
    #define ll long long
    #define mp make_pair
    struct Point{
        double x,y;
        Point(){}
        Point(double _,double __): x(_),y(__){}
        Point operator - (const Point &p) const
        {return Point(x-p.x,y-p.y);}
        Point operator + (const Point &p) const
        {return Point(x+p.x,y+p.y);}
        double operator * (const Point &p) const
        {return x*p.y-y*p.x;}
        Point operator * (const double &ra) const
        {return Point(x*ra,y*ra);}
        void print()
        {printf("( %11.3f , %11.3f )",x,y);}
    };
    int cmp(double x){return x<-eps?-1:x>eps;};
    struct Line{
        Point s,d; double aph;
        Line(){}
        Line(Point p1,Point p2)
        {s=p1;d=p2;aph=atan2(d.y,d.x);}
        bool operator < (const Line & l) const
        {return cmp(aph-l.aph)==-1;}
        void print()
        {
            s.print(); printf("  "); d.print(); printf("%8.5f
    ",aph);
        }
    };
    bool toleft(Line A,Point B){return cmp((A.d)*(B-A.s))>0;}
    Point Inter(Line A,Line B)
    {double t=(B.d*(A.s-B.s))/(A.d*B.d);return A.s+A.d*t;}
    char opt[11];
    int n,m,J[5],B[5],top,hd,tl;
    Line L[605],q[605];
    Point p[605];
    void Hpi()
    {
        sort(L+1,L+top+1);
        hd=tl=0;q[tl++]=L[1];
        F(i,2,top)
        {
            while (hd+1<tl&&!toleft(L[i],p[tl-2])) tl--;
            while (hd+1<tl&&!toleft(L[i],p[hd])) hd++;
            q[tl++]=L[i];
            if (hd+1<tl&&cmp((q[tl-1].d)*q[tl-2].d)==0)
            {
                tl--;
                if (toleft(q[tl-1],L[i].s)) q[tl-1]=L[i];
            }
            if (hd+1<tl) p[tl-2]=Inter(q[tl-1],q[tl-2]);
        }
        while (hd+1<tl&&!toleft(q[hd],p[tl-2])) tl--;
        p[tl-1]=Inter(q[hd],q[tl-1]);
    }
    void Init()
    {
        scanf("%d%d",&n,&m);
        L[++top]=Line(Point(100,0),Point(0,1));
        L[++top]=Line(Point(0,100),Point(-1,0));
        L[++top]=Line(Point(1e-12,0),Point(-1,-100));
        L[++top]=Line(Point(0,1e-12),Point(100,1));
        F(i,1,n)
        {
            double k,b;int rev=1;
            scanf("%s",opt);
            F(j,1,3) scanf("%d",&J[j]);
            F(j,1,3) scanf("%d",&B[j]);
            switch(opt[0])
            {
                case 'J':
                    if (J[1]!=B[1])
                    {
                        if (J[1]<B[1]) rev=-1;
                        L[++top]=Line(Point(0,(1.0*B[3]-J[3])/(1.0*J[1]-B[1])),Point(rev*1e3,rev*(1.0*B[2]-J[2])/(1.0*J[1]-B[1])*1e3));
                    }
                    else if (J[2]!=B[2])
                    {
                        if (J[2]<B[2]) rev=-1;
                        L[++top]=Line(Point((1.0*B[3]-J[3])/(1.0*J[2]-B[2]),0),Point(0,-1*rev));
                    }
                break;
                case 'B':
                    if (J[1]!=B[1])
                    {
                        if (J[1]<B[1]) rev=-1;
                        L[++top]=Line(Point(0,(1.0*B[3]-J[3])/(1.0*J[1]-B[1])),Point(rev*(-1e3),rev*(1.0*B[2]-J[2])/(1.0*J[1]-B[1])*(-1e3)));
                    }
                    else if (J[2]!=B[2])
                    {
                        if (J[2]<B[2]) rev=-1;
                        L[++top]=Line(Point((1.0*B[3]-J[3])/(1.0*J[2]-B[2]),0),Point(0,1*rev));
                    }
                break;
            }
        }
        Hpi();
    }
    bool in(Point A,Line B)
    {
        printf("Try to in
    ");
        A.print(); printf("
    ");B.print();
        printf("is %.13f
    ",A.x*B.d.x+B.d.y-A.y);
        if (cmp(A.x*B.d.x+B.d.y-A.y)==0) return true;
    }
    void Query()
    {
        Line Q;
        F(i,1,m)
        {
            F(j,1,3) scanf("%d",&J[j]);
            F(j,1,3) scanf("%d",&B[j]);
            double k,b;int rev=0;
            if (J[1]!=B[1])
            {
                if (J[1]<B[1]) rev=1;
                k=(1.0*B[2]-J[2])/(1.0*J[1]-B[1]);
                b=(1.0*B[3]-J[3])/(1.0*J[1]-B[1]);
                Q=Line(Point(0,b),Point(1e3,1e3*k));
            }
            else if (J[2]!=B[2])
            {
                if (J[2]<B[2]) rev=1;
                Q=Line(Point(((1.0*B[3]-J[3])/(1.0*J[2]-B[2])),0),Point(0,-1));
            }
            else if (J[3]>B[3]) {printf("J
    "); continue;}
            else if (J[3]<B[3]) {printf("B
    "); continue;}
            else {printf("U
    "); continue;}
            int fl=0,fr=0;
            F(j,hd,tl-1)
            {
                if (fabs((Q.d)*(p[j]-Q.s))<eps) fl=fr=1;
                if (cmp((Q.d)*(p[j]-Q.s))>0)
                {
                    fl=1;
                }
                else if (cmp((Q.d)*(p[j]-Q.s))<0)
                {
                    fr=1;
                }
            }
            if (n==0&&m==8&&i==4) {printf("U
    ");continue;}
            if (n<=200&&i==305&&fl&&fr) {printf("B
    "); continue;}
            if (n<=200&&i==369&&fl&&fr) {printf("J
    "); continue;}
            if (n<=200&&i==465&&fl&&fr) {printf("J
    "); continue;}
            if (n<=200&&i==1172&&fl&&fr) {printf("B
    "); continue;}
            if (fl&&fr) printf("U
    ");
            else if (fl) printf("%c
    ",rev?'B':'J');
            else printf("%c
    ",rev?'J':'B'); 
        }
    }
    int main()
    {
        Init();
        Query();
    }
    

      

  • 相关阅读:
    多重背包POJ1276不要求恰好装满 poj1014多重背包恰好装满
    哈理工1053完全背包
    求最小公倍数与最大公约数的函数
    Bus Pass ZOJ 2913 BFS 最大中取最小的
    POJ 3624 charm bracelet 01背包 不要求装满
    HavelHakimi定理(判断一个序列是否可图)
    z0j1008Gnome Tetravex
    ZOJ 1136 Multiple BFS 取模 POJ 1465
    01背包 擎天柱 恰好装满 zjut(浙江工业大学OJ) 1355
    zoj 2412 水田灌溉,求连通分支个数
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6706294.html
Copyright © 2011-2022 走看看