zoukankan      html  css  js  c++  java
  • 半平面交 poj1279

    Source Code

    Problem: 1279   User: Faker_fan
    Memory: 296K   Time: 0MS
    Language: C++   Result: Accepted
      • Source Code
    #include <iostream>
    #include <string.h>
    #include <queue>
    #include <stdio.h>
    #include <algorithm>
    #include <math.h>
    typedef long long ll;
    using namespace std;
    const int maxn=1e4+10;
    const int mod=998244353;
    using namespace std;
    
    const double eps = 1e-8;
    int sgn(double x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0) return -1;
        return 1;
    }
    struct Point
    {
        double x,y;
        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;
        }
        double operator ==(const Point &b)const
        {
            return x==b.x&&y==b.y;
        }
    };
    struct Line
    {
        Point s,e;
        Line(){}
        Line(Point _s,Point _e)
        {
            s = _s;e = _e;
        }
    };
    double xmult(Point p0,Point p1,Point p2) //p0p1 X p0p2
    {
        return (p1-p0)^(p2-p0);
    }
    double xmult(Point p0,Point p1,Point p2,Point p3) //p0p1 X p2p3
    {
        return (p1-p0)^(p3-p2);
    }
    bool Seg_inter_line(Line l1,Line l2) //判断直线l1和线段l2是否相交
    {
        return sgn(xmult(l2.s,l1.s,l1.e))*sgn(xmult(l2.e,l1.s,l1.e)) <= 0;
    }
    Point getIntersectPoint(Line a, Line b) {
      double a1 = a.s.y - a.e.y, b1 = a.e.x - a.s.x, c1 = a.s.x * a.e.y - a.e.x * a.s.y;
      double a2 = b.s.y - b.e.y, b2 = b.e.x - b.s.x, c2 = b.s.x * b.e.y - b.e.x * b.s.y;
      return Point((c1*b2-c2*b1)/(a2*b1-a1*b2), (a2*c1-a1*c2)/(a1*b2-a2*b1));
    }
    double dist(Point a,Point b)
    {
        return sqrt( (b - a)*(b - a) );
    }
    
    
    //半平面交s
    int neihe_num;
    Point dad_anticlock[maxn],neihe[maxn];//输入弄好就行了
    Line dad_half_line[maxn],que[maxn];
        //得到极角角度
    double getAngle(Point a) {
      return atan2(a.y, a.x);
    }
        
    
    //得到极角角度
    double getAngle(Line a) {
      return atan2(a.e.y - a.s.y, a.e.x - a.s.x);
    }
    bool onRight(Line a, Line b, Line c) {
      Point o = getIntersectPoint(b, c);
      if (((a.e - a.s) ^ (o - a.s)) < 0) return true;
      return false;
    }
    bool cmp_half(Line L1,Line L2)
    {
        Point va = L1.e - L1.s, vb = L2.e - L2.s;
        double A =  getAngle(va), B = getAngle(vb);
        if (fabs((double)(A - B)) < eps) return ((va) ^ (L2.e - L1.s)) >= 0;
        return A < B;
    }
    bool Is_half(int num)
    {
        for(int i=0;i<num;i++)
        {
            dad_half_line[i].s=dad_anticlock[i];
            dad_half_line[i].e=dad_anticlock[(i+1)%num];
        }
        sort(dad_half_line, dad_half_line+num, cmp_half);
        
        int head = 0, tail = 0, cnt = 0;//模拟双端队列
        //去重,极角相同时取最后一个。
        for (int i = 0; i < num - 1; i++) {
            if (fabs(getAngle(dad_half_line[i]) - getAngle(dad_half_line[i + 1])) < eps) {
                continue;
            }
            dad_half_line[cnt++] = dad_half_line[i];
        }
        dad_half_line[cnt++] = dad_half_line[num - 1];
        
        
        for (int i = 0; i < cnt; i++) {
            //判断新加入直线产生的影响
            while(tail - head > 1 && onRight(dad_half_line[i], que[tail - 1], que[tail - 2])) tail--;
            while(tail - head > 1 && onRight(dad_half_line[i], que[head], que[head + 1])) head++;
            que[tail++] = dad_half_line[i];
          }
          //最后判断最先加入的直线和最后的直线的影响
          while(tail - head > 1 && onRight(que[head], que[tail - 1], que[tail - 2])) tail--;
          while(tail - head > 1 && onRight(que[tail - 1], que[head], que[head + 1])) head++;
          if (tail - head < 3) return false;
        neihe[0]=getIntersectPoint(que[head],que[tail-1]);
        for(int i=1;i<tail-head;i++)
            neihe[i]=getIntersectPoint(que[i+head],que[(i+head-1)]);
        neihe_num=tail-head;
          return true;//最后拿到的是一些构成内核的线段
    }
    
    //半平面交e
    
    //多边形面积s
    double mianji_duobianxing(Point *a,int num)
    {
        double res=0;
        for(int i=0;i<num;i++)
        {
            res+=a[i]^a[(i+1)%num];
        }
        res/=2;
        return abs(res);
    }
    //多边形面积e
    int main()
    {
        int n,T;
        cin>>T;
        while(T--)
        {
            cin>>n;
            for(int i=0;i<n;i++)
            {
                cin>>dad_anticlock[n-i-1].x>>dad_anticlock[n-i-1].y;
                
            }
            
            if(Is_half(n))
            {
                double res=0;
                res=mianji_duobianxing(neihe, neihe_num);
                printf("%.2lf
    ",res);
            }
            else
            {
                cout<<"0.00"<<endl;
            }
        }
    }
  • 相关阅读:
    python基础——反射
    python基础——模块
    python基础——异常处理、递归
    python基础——生成器与迭代器
    python基础——装饰器
    Python常见面试题
    Socket网络编程
    爬虫解析相关
    爬虫请求相关
    初识爬虫
  • 原文地址:https://www.cnblogs.com/King-of-Dark/p/13226976.html
Copyright © 2011-2022 走看看