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();
    }
    

      

  • 相关阅读:
    java enum
    how to build a runable jar
    ZF报错解决方法·
    Apache配置本地测试多网站域名与虚拟主机
    PHP实现MVC开发: 一个简单的MVC
    收藏PHP常用函数
    数据库密码忘记…………找回方法
    php读取excel文件reader.php excel操作类使用
    积累的常用linux命令
    JS控制浏览器大小
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6706294.html
Copyright © 2011-2022 走看看