zoukankan      html  css  js  c++  java
  • Art Gallery

    同上面几道题差不多,需要先求出来内核,然后直接用叉积求出来面积即可。

    代码如下:

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    #include<math.h>
    #include<queue>
    using namespace std;
    
    const int MAXN = 1507;
    const int oo = 1e9+7;
    const double EPS = 1e-10;
    
    int Sign(double t)
    {
        if(t > EPS)
            return 1;
        if(fabs(t) < EPS)
            return 0;
        return -1;
    }
    
    struct Point
    {
        double  x, y;
        Point(double x=0, double y=0):x(x),y(y){}
        Point operator - (const Point &t)const{
            return Point(x-t.x, y-t.y);
        }
        double operator ^(const Point &t)const{
            return x*t.y - y*t.x;
        }
    
    }p[MAXN], in[MAXN];
    struct Segment
    {
        Point S, E;
        double a, b, c;
        Segment(Point S=0, Point E=0):S(S), E(E){
            a = S.y - E.y;
            b = E.x - S.x;
            c = E.x*S.y - S.x*E.y;
        }
        Point crossNode(const Segment &t)const{
            Point res;
    
            res.x = (c*t.b-t.c*b) / (a*t.b-t.a*b);
            res.y = (c*t.a-t.c*a) / (b*t.a-t.b*a);
    
            return res;
        }
        int Mul(const Point &t)
        {///用叉积判断方向
            return Sign((E-S)^(t-S));
        }
    };
    int CutPoly(Segment L, int N)
    {
        Point tmp[MAXN];
        int cnt = 0;
    
        for(int i=1; i<=N; i++)
        {
            if(L.Mul(in[i]) <= 0)
                tmp[++cnt] = in[i];
            else
            {
                if(L.Mul(in[i-1]) < 0)///求出交点
                    tmp[++cnt] = L.crossNode(Segment(in[i-1],in[i]));
                if(L.Mul(in[i+1]) < 0)
                    tmp[++cnt] = L.crossNode(Segment(in[i],in[i+1]));
            }
        }
    
        for(int i=1; i<=cnt; i++)
            in[i] = tmp[i];
        in[0] = in[cnt], in[cnt+1] = in[1];
    
        return cnt;
    }
    
    int main()
    {
        int T;
    
        scanf("%d", &T);
    
        while(T--)
        {
            int N, M;
            double s=0;
    
            scanf("%d", &N);
    
            for(int i=1; i<=N; i++)
            {
                scanf("%lf%lf", &p[i].x, &p[i].y);
                in[i] = p[i];
            }
            if(s < 0)
            {
                for(int i=1; i<=N/2; i++)
                {
                    swap(p[i], p[N-i+1]);
                    swap(in[i], in[N-i+1]);
                }
            }
    
            in[0] = p[0] = p[N];
            in[N+1] = p[N+1] = p[1];
            M = N;
    
            for(int i=1; i<=N; i++)
                M = CutPoly(Segment(p[i],p[i+1]), M);
    
            for(int i=1; i<=M; i++)
            {
                s += in[i].x*in[i+1].y - in[i].y*in[i+1].x;
            }
    
            printf("%.2f
    ", fabs(s)/2.0);
        }
    
        return 0;
    }
  • 相关阅读:
    Linux Core Dump
    ODP.NET Managed正式推出
    获取EditText的光标位置
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4920774.html
Copyright © 2011-2022 走看看