版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}