CF 87E 题解 Mogohu-Rea Idol

来源:互联网 发布:微商货源源码 编辑:程序博客网 时间:2024/04/30 15:25

看了题解敲出来的,还wa了那么多发,吸取了一个教训,判断点在多边形内还有多边形上,要保证凸包任意三点不共线,否则会出错,

题解也很简单。。就是对三个凸包求Minkowski和,然后判断点是否在凸多边形内即可

#include<stdio.h>#include<iostream>#include<math.h>#include<algorithm>using namespace std;#define eps 1e-8int sig(double x) {return (x>eps)-(x<-eps);}const double pi=acos(-1.0);struct P{    double x,y,ang;    P(double a=0,double b=0):x(a),y(b){}    P operator +(const P &a)const{        return P(x+a.x,y+a.y);    }    P operator -(const P &a)const{        return P(x-a.x,y-a.y);    }    P operator *(const double a)const{        return P(x*a,y*a);    }    P operator /(const double a)const{        return P(x/a,y/a);    }    double operator *(const P &a)const{        return x*a.x+y*a.y;    }    double operator ^(const P &a)const{        return x*a.y-y*a.x;    }    bool operator ==(const P &a)const{        return sig(x-a.x)==0&&sig(y-a.y)==0;    }    bool on(P a,P b)    {        if(a==*this||b==*this) return 1;        P v1=a-*this,v2=b-*this;        return !sig(v1^v2)&&sig(v1*v2)<=0;    }};double across(P a,P b,P c){    return (b-a)^(c-a);}int cmp1(P a,P b){    if(sig(a.x-b.x)!=0) return a.x<b.x;    else return a.y<b.y;}int Graham(P *p,int n,P *q){    sort(p,p+n,cmp1);    int m=0;    for(int i=0;i<n;i++)    {        while(m>1&&sig((q[m-1]-q[m-2])^(p[i]-q[m-2]))<=0) m--;        q[m++]=p[i];    }    int k=m;    for(int i=n-2;i>=0;i--)    {        while(m>k&&sig((q[m-1]-q[m-2])^(p[i]-q[m-2]))<=0) m--;        q[m++]=p[i];    }    if(n>1) m--;    return m;}int inside(P a,P b,P c,P p){    double s=fabs(across(a,b,c));    double sa=fabs(across(a,b,p));    double sb=fabs(across(a,c,p));    double sc=fabs(across(b,c,p));    return (s==(sa+sb+sc));}bool inpoly(P a,P *p,int n){    if(across(p[0],p[1],a)<0||across(p[0],p[n-1],a)>0) return 0;    int r=n-1,l=1;    while(r-l>1)    {        int m=(l+r)/2;        if(across(p[0],p[m],a)>=0) l=m;        else r=m;    }    return inside(p[0],p[l],p[r],a);}P p1[50010],p2[50010],p3[50010],p[150010],pp[150010],q[150010];int cnt;P input(int n,P *ch){    P a;    for(int i=0;i<n;i++)        {            scanf("%lf%lf",&ch[i].x,&ch[i].y);            if(i==0) a=ch[i];            else            {                if(a.y>ch[i].y) a=ch[i];                else if(sig(a.y-ch[i].y)==0)                {                    if(ch[i].x<a.x) a=ch[i];                }            }        }        ch[n]=ch[0];    for(int i=1;i<=n;i++)    {        pp[cnt]=ch[i]-ch[i-1];        pp[cnt].ang=atan2(pp[cnt].y,pp[cnt].x);        if(sig(pp[cnt].ang)<0) pp[cnt].ang+=2*pi;        cnt++;    }    return a;}int cmp(P a,P b){    return a.ang<b.ang;}int main(){    int n,m;    //freopen("out.txt","w",stdout);    while(scanf("%d",&n)!=EOF)    {        cnt=0;        P a=input(n,p1);        scanf("%d",&n);        a=a+input(n,p2);        scanf("%d",&n);        a=a+input(n,p3);        p[0]=a;        sort(pp,pp+cnt,cmp);        for(int i=1;i<=cnt;i++)        {            p[i]=p[i-1]+pp[i-1];        }        cnt=Graham(p,cnt,q);        //for(int i=0;i<cnt;i++)            //cout<<q[i].x<<" "<<q[i].y<<endl;        scanf("%d",&m);        for(int i=0;i<m;i++)        {            P b;            scanf("%lf%lf",&b.x,&b.y);            b=b*3;            //printf("%lf %lf\n",b.x,b.y);            if(inpoly(b,q,cnt)==1)                printf("YES\n");            else                printf("NO\n");        }    }    return 0;}/*43 36 36 63 64-3 3-3 6-6 6-6 343 -33 -66 -66 -336-1 -1-1 0-1 1-1 2-1 3-1 40 -10 00 10 20 30 41 -11 01 11 21 31 42 -12 02 12 22 32 43 -13 03 13 23 33 44 -14 04 14 24 34 4*/


0 0
原创粉丝点击