Building HDU - 5033离线+斜率凸包

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leekerian/article/details/82080837

真的是自闭到哭,,一度躺在床上怀疑我是不是要死掉了,,,,根本a不掉,,,结果是错在cont++的位置????????

好难过,,,

思路简单清晰,离线左右构建凸包维护凸包就好了,,,

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int maxn=200005;
const double eps=1e-8;
const double PI=acos(-1.0);

int sgn(double x)
{
    if(fabs(x)<eps)
        return 0;
    if(x<0)
        return -1;
    else
        return 1;
}
struct Point
{
    double x,y;
    int flag;
    double at1,at2;
    int index;
    Point(){}
    Point(double _x,double _y)
    {
        x=_x;
        y=_y;
    }
    Point operator -(const Point &b)const
    {
        return Point(x-b.x,y-b.y);
    }
    double operator ^(const Point &b)const
    {
        return x*b.y-y*b.x;
    }
    double operator *(const Point &b)const
    {
        return x*b.x+y*b.y;
    }
};

Point p[maxn];


bool cmp(Point a,Point b)
{
    if(a.x!=b.x)
        return a.x<b.x;
    else
        return a.y>b.y;
}

bool cmp1(Point a,Point b)
{
    if(a.x!=b.x)
        return a.x<b.x;
    else
        return a.y<b.y;
}

int top;
Point p1[maxn];
void anderw(int n)
{
    sort(p,p+n,cmp);
    top=0;
    for(int i=0;i<n;i++)
    {
        if(p[i].flag==1)
        {
            int l=0;
            int r=top-1;
            int mid;
            while(l<=r)
            {
                mid=(l+r)>>1;
                if(sgn((p[i]-p1[0])^(p1[mid]-p1[0]))>=0)
                    l=mid+1;
                else
                    r=mid-1;
            }
            mid=(l+r)>>1;
            while(mid>0&&sgn((p1[mid]-p[i])^(p1[mid-1]-p[i]))<=0)
            {
                p[i].at1=min(p[i].at1,atan2(p1[mid].y,p1[mid].x-p[i].x));
                mid=mid-1;
            }
            if(mid>=0)
            p[i].at1=min(p[i].at1,atan2(p1[mid].y,p1[mid].x-p[i].x));
        }
        else
        {
            while(top>1&&sgn((p1[top-1]-p1[top-2])^(p[i]-p1[top-2]))>=0)
                top--;
            p1[top++]=p[i];
        }
    }
    sort(p,p+n,cmp1);
    top=0;
    for(int i=n-1;i>=0;i--)
    {
        if(p[i].flag==1)
        {
            int l=0;
            int r=top-1;
            int mid;
            while(l<=r)
            {
                mid=(l+r)>>1;
                if(sgn((p1[mid]-p1[0])^(p[i]-p1[0]))>=0)
                    l=mid+1;
                else
                    r=mid-1;
            }
            mid=(l+r)>>1;
           // while(mid>=0&&p1[mid].x==p[i].x)
               // mid=mid-1;
            while(mid>0&&sgn((p1[mid]-p[i])^(p1[mid-1]-p[i]))>=0)
            {
                p[i].at2=max(p[i].at2,atan2(p1[mid].y,p1[mid].x-p[i].x));
                mid=mid-1;
            }
            if(mid>=0)
            p[i].at2=max(p[i].at2,atan2(p1[mid].y,p1[mid].x-p[i].x));
        }
        else
        {
            while(top>1&&sgn((p1[top-1]-p1[top-2])^(p[i]-p1[top-2]))<=0)
                top--;
            p1[top++]=p[i];
        }
    }
}

bool cmp2(Point a,Point b)
{
    return a.index<b.index;

}
int main()
{
    //freopen("D://ACM//duipai//data.txt","r",stdin);
	//freopen("D://ACM//duipai//wa.txt","w",stdout);
    int T;
    cin>>T;
    int cont=1;
    while(T--)
    {
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            scanf("%lf %lf",&p[i].x,&p[i].y);
            p[i].flag=0;
            p[i].index=i;
        }
        int m;
        cin>>m;
        for(int i=n;i<n+m;i++)
        {
            double x;
            scanf("%lf",&x);
            p[i].x=x;
            p[i].y=0;
            p[i].flag=1;
            p[i].at1=PI;
            p[i].at2=0;
            p[i].index=i;
        }
        anderw(n+m);
        sort(p,p+n+m,cmp2);
        printf("Case #%d:\n",cont++);
        for(int i=n;i<n+m;i++)
        {
            if(p[i].flag==1)
            {
                //cont++; 好难过啊,就是错在这里!!!!!!!!
                 //printf("%.12lf\n",p[i].at1*180/PI);
               // printf("%.12lf\n",p[i].at2*180/PI);
                printf("%.10lf\n",(p[i].at1-p[i].at2)*180.0/PI);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/leekerian/article/details/82080837