题意:链接
方法:半平面交判定多边形内核存在性。
解析:
半平面交裸题。
练模板题。
首先按照逆时针搞出所有的边。
然后极角排序。
之后搞一个双端队列,维护原来的交点在新加的直线的左边。
最后扫一下队列即可。
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 110
#define eps 1e-8
using namespace std;
int t,n,halfplanes;
struct Point
{
double x,y;
Point(){}
Point(double a,double b){x=a,y=b;}
Point operator + (const Point &a)
{return Point(x+a.x,y+a.y);}
Point operator - (const Point &a)
{return Point(x-a.x,y-a.y);}
Point operator * (double rate)
{return Point(x*rate,y*rate);}
double operator * (const Point &a)
{return x*a.x+y*a.y;}
double operator ^ (const Point &a)
{return x*a.y-y*a.x;}
}p[N],pt[N];
struct HalfPlane
{
Point p,v;
double angle;
HalfPlane(){}
HalfPlane(Point _s,Point _t):p(_s),v(_t)
{
angle=atan2(v.y,v.x);
}
friend bool operator < (HalfPlane a,HalfPlane b)
{
return a.angle<b.angle;
}
}hp[N],q[N];
Point Get_Intersection(HalfPlane &l1,HalfPlane &l2)
{
Point u=l1.p-l2.p;
double tmp=(l2.v^u)/(l1.v^l2.v);
return l1.p+l1.v*tmp;
}
bool onleft(HalfPlane &L,Point p)
{
return (L.v^(p-L.p))>=0;
}
int HalfPlaneIntersect()
{
int l=1,r=1;
q[1]=hp[1];
for(int i=2;i<=halfplanes;i++)
{
while(l<r&&!onleft(hp[i],p[r-1]))r--;
while(l<r&&!onleft(hp[i],p[l]))l++;
if(fabs(hp[i].v^q[r].v)<eps)
q[r]=onleft(q[r],hp[i].p)?hp[i]:q[r];
else q[++r]=hp[i];
if(l<r)p[r-1]=Get_Intersection(q[r],q[r-1]);
}
while(l<r&&!onleft(q[l],p[r-1]))r--;
return r-l>1;
}
void MakeLine(Point &a,Point &b)
{
hp[++halfplanes]=HalfPlane(a,b-a);
}
int main()
{
scanf("%d",&t);
while(t--)
{
halfplanes=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&pt[i].x,&pt[i].y);
for(int i=1;i<n;i++)
MakeLine(pt[i+1],pt[i]);
MakeLine(pt[1],pt[n]);
sort(hp+1,hp+halfplanes+1);
int ans=HalfPlaneIntersect();
if(ans)puts("YES");
else puts("NO");
}
}