POJ 3335 Rotating Scoreboard

来源:互联网 发布:退伍军人召回通知软件 编辑:程序博客网 时间:2024/05/01 08:17

半平面交。

判断多边形核是否存在,用半平面交。

半平面交资料传送门:算法合集之《半平面交的新算法及其实用价值》

提交的时候语言选错,蜜汁CE一次- -

#include<cstdio>#include<cmath>#include<algorithm>#define N 105using namespace std;struct point{    double x, y;}p[N];struct line{    point a, b;    double angle;}l[N];int lcnt=0, rank[N], q[N];int dblcmp(double k){    if(fabs(k)<1e-8)return 0;    return k>0?1:-1;}double multi(point a, point b, point c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}bool cmp(int a, int b){    int d=dblcmp(l[a].angle-l[b].angle);    if(!d){return dblcmp(multi(l[a].a,l[b].a,l[b].b))<0;}    else return d>0;}void add_line(point a, point b){    l[++lcnt]=(line){a,b,atan2(b.y-a.y,b.x-a.x)};    rank[lcnt]=lcnt;}point intersect(line l1, line l2)  {      point p;    double dot1, dot2;      dot1 = multi(l2.a, l1.b, l1.a);      dot2 = multi(l1.b, l2.b, l1.a);      p.x = (l2.a.x * dot2 + l2.b.x * dot1) / (dot2 + dot1);      p.y = (l2.a.y * dot2 + l2.b.y * dot1) / (dot2 + dot1);      return p;}  bool judge(line l0, line l1, line l2){    point p = intersect(l1,l2);    return dblcmp(multi(p,l0.a,l0.b))>0;}bool HPI(){    sort(rank+1,rank+1+lcnt,cmp);    int j=1;    for(int i = 2; i <= lcnt; i++)    {        if(dblcmp(l[rank[i]].angle-l[rank[j]].angle))            rank[++j]=rank[i];    }    lcnt=j;     int head=0, tail=2;    q[0]=rank[1];    q[1]=rank[2];    for(int i = 3; i <= lcnt; i++)    {        while(tail-head>1 && judge(l[rank[i]],l[q[tail-1]],l[q[tail-2]]))tail--;        while(tail-head>1 && judge(l[rank[i]],l[q[head]],l[q[head+1]]))head++;        q[tail++]=rank[i];    }    while(tail-head>1 && judge(l[q[tail-1]],l[q[head]],l[q[head+1]]))head++;    while(tail-head>1 && judge(l[q[head]],l[q[tail-1]],l[q[tail-2]]))tail--;    return tail-head>2;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        lcnt=0;        int n;        scanf("%d",&n);        for(int i = 1; i <= n; i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        for(int i = 1; i < n; i++)            add_line(p[i],p[i+1]);        add_line(p[n],p[1]);        if(HPI())printf("YES\n");        else printf("NO\n");    }}
1 0
原创粉丝点击