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\n",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\n");
    A.print(); printf("\n");B.print();
    printf("is %.13f\n",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\n"); continue;}
        else if (J[3]<B[3]) {printf("B\n"); continue;}
        else {printf("U\n"); 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\n");continue;}
        if (n<=200&&i==305&&fl&&fr) {printf("B\n"); continue;}
        if (n<=200&&i==369&&fl&&fr) {printf("J\n"); continue;}
        if (n<=200&&i==465&&fl&&fr) {printf("J\n"); continue;}
        if (n<=200&&i==1172&&fl&&fr) {printf("B\n"); continue;}
        if (fl&&fr) printf("U\n");
        else if (fl) printf("%c\n",rev?'B':'J');
        else printf("%c\n",rev?'J':'B'); 
    }
}
int main()
{
    Init();
    Query();
}

  

posted @ 2017-04-13 21:39  SfailSth  阅读(177)  评论(0编辑  收藏  举报