题目链接:http://poj.org/problem?id=1279
题意:求多边形的核。
思路:枚举每条边,对于其他的点若在这条边的左侧则加入;其他的边与这条边相交则将交点加入。
struct point
{
double x,y;
point(){}
point(double _x,double _y)
{
x=_x;
y=_y;
}
void read()
{
RD(x,y);
}
void output()
{
printf("(%.2lf %.2lf)",x,y);
}
point operator+(point a)
{
return point(x+a.x,y+a.y);
}
point operator-(point a)
{
return point(x-a.x,y-a.y);
}
double operator*(point a)
{
return x*a.y-y*a.x;
}
point operator*(double t)
{
return point(x*t,y*t);
}
point operator/(double t)
{
return point(x/t,y/t);
}
};
point a[N],b[N];
int n,m,C;
int DB(double x)
{
if(x>1e-10) return 1;
if(x<-1e-10) return -1;
return 0;
}
double cross(point a,point b,point t)
{
return point(b-a)*point(t-a);
}
double getArea(point p[],int n)
{
double ans=0;
int i;
p[n]=p[0];
FOR0(i,n) ans+=p[i]*p[i+1];
return ans/2;
}
point getCross(point a,point b,point p,point q)
{
double s1=(a-p)*(b-p);
double s2=(b-q)*(a-q);
double t=s1+s2;
return (p*s2+q*s1)/(s1+s2);
}
void getCore(point a[],int n,point b[],int &m)
{
int i,j,x,y,u,v;
point c[N],temp;
a[n]=a[0];
FOR0(i,n+1) c[i]=a[i];
x=n;
FOR0(i,n)
{
y=0;
FOR0(j,x)
{
u=DB(cross(a[i],a[i+1],c[j]));
v=DB(cross(a[i],a[i+1],c[j+1]));
if(u>=0) b[y++]=c[j];
if(u*v==-1)
{
b[y++]=getCross(a[i],a[i+1],c[j],c[j+1]);
}
}
b[y]=b[0];
x=y;
FOR0(j,y+1) c[j]=b[j];
}
m=y;
}
int main()
{
RD(C);
while(C--)
{
RD(n);
int i;
FOR0(i,n) a[i].read();
double s=getArea(a,n);
if(DB(s)==-1)
{
FOR0(i,n/2) swap(a[i],a[n-1-i]);
}
getCore(a,n,b,m);
s=getArea(b,m);
printf("%.2lf\n",s);
}
return 0;
}