• POJ 1279 Art Gallery 半平面交求多边形核


    第一道半平面交,只会写N^2。

    将每条边化作一个不等式,ax+by+c>0,所以要固定顺序,方便求解。

    半平面交其实就是对一系列的不等式组进行求解可行解。

    如果某点在直线右侧,说明那个点在区域内,否则出现在左边,就可能会有交点,将交点求出加入。

    //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #define ll long long
    #define Max(a,b) (((a) > (b)) ? (a) : (b))
    #define Min(a,b) (((a) < (b)) ? (a) : (b))
    #define Abs(x) (((x) > 0) ? (x) : (-(x)))
    using namespace std;
    
    const int MAXN = 1555;
    const double eps = 1e-8;
    
    struct POINT{
        double x;
        double y;
        POINT() : x(0), y(0) {};
        POINT(double _x_, double _y_) : x(_x_), y(_y_) {};
    };
    
    struct LINE{
        POINT a;
        POINT b;
        LINE() {};
        LINE(POINT _a_, POINT _b_) : a(_a_), b(_b_) {};
    };
    
    POINT point[MAXN];//记录最开始的多边形
    POINT temp[MAXN]; //临时保存新切割的多边形
    POINT ans[MAXN]; //保存新切割出的多边形
    LINE lline;
    int n,m;//n的原先的点数,m是新切割出的多边形的点数
    
    void Coefficient(const LINE & L, double & A, double & B, double & C){
        A = L.b.y - L.a.y;
        B = L.a.x - L.b.x;
        C = L.b.x * L.a.y - L.a.x * L.b.y;
    }
    
    double Cross(const POINT & a, const POINT & b, const POINT &o){
        return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
    }
    
    POINT Intersection(const LINE & A, const LINE & B){
        double A1, B1, C1;
        double A2, B2, C2;
        Coefficient(A, A1, B1, C1);
        Coefficient(B, A2, B2, C2);
        POINT temp_point(0, 0);
        temp_point.x = -(B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);
        temp_point.y =  (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
        return temp_point;
    }
    
    //求面积,正为顺时针,和叉积写法有关
    double PointArea(POINT p[],int n){
        double area = 0;
        for(int i = 2; i < n; ++i)
            area += Cross(p[1], p[i], p[i+1]);
        return -area / 2.0;
    }
    
    void Cut(){  //用直线ax+by+c==0切割多边形
        int cut_m = 0, i;
        double a, b, c;
        Coefficient(lline, a, b, c);
        for(i = 1; i <= m; ++i){
            if(a * ans[i].x + b*ans[i].y + c >= 0)  //题目是顺时钟给出点的,所以一个点在直线右边的话,那么带入值就会大于等于0
                temp[++cut_m] = ans[i];         //说明这个点还在切割后的多边形内,将其保留
            else{
                if(a * ans[i - 1].x + b * ans[i - 1].y + c > 0){   //该点不在多边形内,但是它和它相邻的点构成直线与
                    LINE line1(ans[i - 1], ans[i]); //ax+by+c==0所构成的交点可能在新切割出的多边形内,
                    temp[++cut_m] = Intersection(lline, line1); //所以保留交点
                }
                if(a * ans[i + 1].x + b * ans[i + 1].y + c > 0){
                    LINE line1(ans[i + 1], ans[i]);
                    temp[++cut_m] = Intersection(lline, line1); //所以保留交点
                }
            }
        }
        for(i = 1; i <= cut_m; ++i) ans[i] = temp[i];
        ans[cut_m + 1] = temp[1];
        ans[0] = temp[cut_m];
        m = cut_m;
    }
    
    
    void solve(){
        int i;
        point[0] = point[n];
        point[n+1] = point[1];
        for(i = 0; i <= n + 1; ++i){
            ans[i] = point[i];
        }
        m = n;
        for(i = 1;i <= n; ++i){
            lline.a = point[i];
            lline.b = point[i + 1]; //根据point[i]和point[i+1]确定直线ax+by+c==0
            Cut();  //用直线ax+by+c==0切割多边形
        }
        printf("%.2f
    ",Abs(PointArea(ans,m)));
    }
    
    int main(){
        int caseNum,i;
        scanf("%d",&caseNum);
        while(caseNum--){
            scanf("%d",&n);
            for(i = 1; i <= n; ++i){
                scanf("%lf%lf",&point[i].x,&point[i].y);
            }
            solve();
        }
        return 0;
    }
  • 相关阅读:
    selenium学习笔记——上传文件
    selenium学习笔记——利用cookie信息直接登录
    Java中的switch分支注意点
    Java中的包
    11月14日用ajax、PHP、session做购物车
    各种进位制转换
    11月13日上午ajax返回数据类型为JSON数据的处理
    11月13日上午省、市、区(县)三级联动
    11月10日下午 ajax做显示信息以后用ajax、Bootstrp做弹窗显示信息详情
    11月10日上午ajax基础知识、用ajax做登录页面、用ajax验证用户名是否可用、ajax动态调用数据库
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/3919779.html
Copyright © 2020-2023  润新知