zoukankan      html  css  js  c++  java
  • POJ 1279 Art Gallery 半平面交/多边形求核

    http://poj.org/problem?id=1279

    顺时针给你一个多边形...求能看到所有点的面积...用半平面对所有边取交即可,模版题

    这里的半平面交是O(n^2)的算法...比较逗比...暴力对每条线段做半平面交...要注意的地方写在注释里了...顺序写反了卡了我好久

    /********************* Template ************************/
    #include <set>
    #include <map>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cassert>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <fstream>
    #include <numeric>
    #include <iomanip>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    
    #define EPS         1e-8
    #define MAXN        10005
    #define MOD         (int)1e9+7
    #define PI          acos(-1.0)
    #define INF         ((1LL)<<50)
    #define max(a,b)    ((a) > (b) ? (a) : (b))
    #define min(a,b)    ((a) < (b) ? (a) : (b))
    #define max3(a,b,c) (max(max(a,b),c))
    #define min3(a,b,c) (min(min(a,b),c))
    #define BUG         cout<<"BUG! "<<endl
    #define LLINE        cout<<"------------------"<<endl
    #define L(t)        (t << 1)
    #define R(t)        (t << 1 | 1)
    #define Mid(a,b)    ((a + b) >> 1)
    #define lowbit(a)   (a & -a)
    #define FIN         freopen("in.txt","r",stdin)
    #pragma comment     (linker,"/STACK:102400000,102400000")
    
    // typedef long long LL;
    // typedef unsigned long long ULL;
    // typedef __int64 LL;
    // typedef unisigned __int64 ULL;
    // int gcd(int a,int b){ return b?gcd(b,a%b):a; }
    // int lcm(int a,int b){ return a*b/gcd(a,b); }
    
    /*********************   F   ************************/
    struct POINT{
        double x,y;
        POINT(double _x = 0, double _y = 0):x(_x),y(_y){}
    }p[MAXN],q[MAXN],t[MAXN];
    int n;
    struct LINE{
         double a,b,c;
         POINT A,B;
         LINE(POINT _a, POINT _b):A(_a),B(_b){
            a=B.y-A.y;
            b=A.x-B.x;
            c=B.x*A.y-A.x*B.y;
         }
    };
    double multiply(POINT sp,POINT ep,POINT op){                //叉积 左+ 右-
        return (sp.x-op.x) * (ep.y-op.y) - (ep.x-op.x) * (sp.y-op.y);
    }
    POINT Intersection(LINE a,LINE b){                          //直线交点
        double u = fabs(b.A.x * a.a + b.A.y * a.b + a.c);
        double v = fabs(b.B.x * a.a + b.B.y * a.b + a.c);
        POINT t;
        t.x = (b.A.x * v + b.B.x * u) / (u + v);
        t.y = (b.A.y * v + b.B.y * u) / (u + v);
        return t;
    }
    double Triangle_area(POINT a,POINT b,POINT c){              //求三角形面积(带符号)
        return multiply(a,b,c)/2;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("outm.txt","w",stdout);
        int ct = 1;
        int T;
        cin>>T;
        while(T--){
            cin>>n;
            for(int i = 0 ; i < n ; i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            //暴力对每一个向量作半平面交 ...即将右侧的点和与其他直线的交点加入集合
            for(int i = 0 ; i < n ; i++) q[i] = p[i];
            int cnt = n;
            for(int i = 0 ; i < n ; i++){
                int c = 0;
                for(int j = 0 ; j < cnt ; j++){
                    //点在右侧
                    if(multiply(p[i],p[(i+1)%n],q[j]) <= EPS) {
                        t[c++] = q[j];
                    }else {     //点在左侧,但是前后线段和该直线有交点
                        //这个顺序不要写反,否则不是顺时针会WA
                        if(multiply(p[i],p[(i+1)%n],q[(j-1+cnt)%cnt]) < -EPS){
                            t[c++] = Intersection(LINE(p[i],p[(i+1)%n]) , LINE(q[j],q[(j-1+cnt)%cnt]));
                        }
                        if(multiply(p[i],p[(i+1)%n],q[(j+1)%cnt]) < -EPS){
                            t[c++] = Intersection(LINE(p[i],p[(i+1)%n]) , LINE(q[j],q[(j+1)%cnt]));
                        }
                    }
                }
                for(int j = 0 ; j < c ; j++) q[j] = t[j];
                cnt = c;
            }
            double area = 0;
            for(int i = 0 ; i < cnt ; i++){
                area += Triangle_area(POINT(0,0),q[i],q[(i+1)%cnt]);
            }
            area = fabs(area);
            printf("%.2lf
    ",area);
        }
        return 0;
    }
  • 相关阅读:
    [备份]部分常用函数
    [考试]20150904
    [考试]20150903
    [未完成][知识点]动态规划优化初步
    [考试]20150822
    [考试]20150821
    [知识点]后缀数组
    [考试]20150816
    [考试]20150815
    BZOJ2815: [ZJOI2012]灾难
  • 原文地址:https://www.cnblogs.com/Felix-F/p/3258475.html
Copyright © 2011-2022 走看看