Cows 计算几何 求凸包 求多边形面积

题目链接:https://cn.vjudge.net/problem/POJ-3348

题意

啊模版题啊

求凸包的面积,除50即可

思路

求凸包的面积,除50即可

提交过程

AC

代码

#include <cmath>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const double eps=1e-10;
struct Point{
    double x, y;

    Point(int x=0, int y=0):x(x), y(y) {}
    // no known conversion for argument 1 from ‘Point‘ to ‘Point&‘
    Point operator + (Point p){return Point(x+p.x, y+p.y);}
    Point operator - (Point p){return Point(x-p.x, y-p.y);}
    Point operator * (double k){return Point(k*x, k*y);}
    Point operator / (double k){return Point(x/k, y/k);}
    bool operator < (Point p) const{return (x==p.x)?(y<p.y):(x<p.x);}   // need eps?
    bool operator == (const Point p) const{return fabs(x-p.x)<eps&&fabs(y-p.y)<eps;}
    double norm(void){return x*x+y*y;}
    double abs(void){return sqrt(norm());}
    double dot(Point p){return x*p.x+y*p.y;}        // cos
    double cross(Point p){return x*p.y-y*p.x;}      // sin
};
struct Segment{Point p1, p2;};
struct Circle{Point o; double rad;};
typedef Point Vector;
typedef vector<Point> Polygon;
typedef Segment Line;

int ccw(Point p0, Point p1, Point p2){
    Vector v1=p1-p0, v2=p2-p0;
    if (v1.cross(v2)>eps) return 1;         // anti-clockwise
    if (v1.cross(v2)<-eps) return -1;       // clockwise
    if (v1.dot(v2)<0) return 2;
    if (v1.norm()<v2.norm()) return -2;
    return 0;
}

Point project(Segment s, Point p){
    Vector base=s.p2-s.p1;
    double k=(p-s.p1).cross(base)/base.norm();
    return s.p1+base*k;
}

Point reflect(Segment s, Point &p){
    return p+(project(s, p)-p)*2;
}

double lineDist(Line l, Point p){
    return abs((l.p2-l.p1).cross(p-l.p1)/(l.p2-l.p1).abs());
}

double SegDist(Segment s, Point p){
    if ((s.p2-s.p1).dot(p-s.p1)<0) return Point(p-s.p1).abs();
    if ((s.p1-s.p2).dot(p-s.p2)<0) return Point(p-s.p2).abs();
    return abs((s.p2-s.p1).cross(p-s.p1)/(s.p2-s.p1).abs());
}

bool intersect(Point p1, Point p2, Point p3, Point p4){
    return ccw(p1, p2, p3)*ccw(p1, p2, p4)<=0 &&
            ccw(p3, p4, p1)*ccw(p3, p4, p2)<=0;
}

Point getCrossPoint(Segment s1, Segment s2){
    Vector base=s2.p2-s2.p1;
    double d1=abs(base.cross(s1.p1-s2.p1));
    double d2=abs(base.cross(s1.p2-s2.p1));
    double t=d1/(d1+d2);
    return s1.p1+(s1.p2-s1.p1)*t;
}

double area(Polygon poly){
    double res=0; long long size=poly.size();
    for (int i=0; i<poly.size(); i++)
        res+=poly[i].cross(poly[(i+1)%size]);
    return abs(res/2);
}

int contain(Polygon poly, Point p){
    int n=poly.size();
    bool flg=false;
    for (int i=0; i<n; i++){
        Point a=poly[i]-p, b=poly[(i+1)%n]-p;
        if (ccw(poly[i], poly[(i+1)%n], p)==0) return 1;    // 1 means on the polygon.
        if (a.y>b.y) swap(a, b);
        if (a.y<0 && b.y>0 && a.cross(b)>0) flg=!flg;
    }return flg?2:0;                                        // 2 fo inner, 0 for outer.
}

Polygon convexHull(Polygon poly){
    if (poly.size()<3) return poly;
    Polygon upper, lower;
    sort(poly.begin(), poly.end());
    upper.push_back(poly[0]); upper.push_back(poly[1]);
    lower.push_back(poly[poly.size()-1]); lower.push_back(poly[poly.size()-2]);
    for (int i=2; i<poly.size(); i++){
        for (int n=upper.size()-1; n>=1 && ccw(upper[n-1], upper[n], poly[i])!=-1; n--)
            upper.pop_back();
        upper.push_back(poly[i]);
    }
    for (int i=poly.size()-3; i>=0; i--){
        for (int n=lower.size()-1; n>=1 && ccw(lower[n-1], lower[n], poly[i])!=-1; n--)
            lower.pop_back();
        lower.push_back(poly[i]);
    }
    for (int i=1; i<lower.size(); i++)
        upper.push_back(lower[i]);
    return upper;
}

int main(void){
    int n;
    double x, y;

    while (scanf("%d", &n)==1 && n){
        Polygon poly, hull;
        for (int i=0; i<n; i++){
            scanf("%lf%lf", &x, &y);
            poly.push_back(Point(x, y));
        }
        printf("%d\n", (long long)area(convexHull(poly))/50);
    }

    return 0;
}
Time Memory Length Lang Submitted
608kB 3526 G++ 2018-08-01 17:22:02

原文地址:https://www.cnblogs.com/tanglizi/p/9403436.html

时间: 2024-11-04 05:07:07

Cows 计算几何 求凸包 求多边形面积的相关文章

凸包 及 多边形面积

首先求多边形面积,这个比较简单,用的就是把一个多边形划分为多个三角形,然后求三角形面积. 代码: double Cross(Vector A,Vector B) { return (A.x*B.y-A.y*B.x); } double ConvexPolygonArea(Point* p,int n)//多边形面积,,点按顺序 { double area=0; for(int i=1;i<n-1;i++) area+=Cross(p[i]-p[0],p[i+1]-p[0]); return ar

凸包,多边形面积,线段在多边形内的判定。

zoj3570  Lott's Seal http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4569 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const double eps=1e-8; 7 const int M=10001

poj1265--Area(求多边形面积+匹克定理)

Area Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5150   Accepted: 2308 Description Being well known for its highly innovative products, Merck would definitely be a good target for industrial espionage. To protect its brand-new resear

POJ 3348 Cows 凸包 求面积

LINK 题意:给出点集,求凸包的面积 思路:主要是求面积的考察,固定一个点顺序枚举两个点叉积求三角形面积和除2即可 /** @Date : 2017-07-19 16:07:11 * @FileName: POJ 3348 凸包面积 叉积.cpp * @Platform: Windows * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : $Id$ */ #include <std

poj 3348 Cows 求凸包面积

题目链接 大意: 求凸包的面积. #include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue>

Board Wrapping(计算几何求凸包加向量的旋转)

UVA - 10652 Board Wrapping Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description Problem B Board Wrapping Input: standard input Output: standard output Time Limit: 2 seconds The small sa

【UVA10652】Board Wrapping(求凸包面积)

点此看题面 大致题意: 告诉你若干个矩形的重心坐标.长.宽和相对\(y\)轴的偏转角度,求矩形面积和与能围住这些矩形的最小凸包面积之比. 矩形面积和 这应该是比较好求的吧. 已经给了你长和宽,直接乘起来累加即可. 最小凸包面积 这道题关键还是在于求凸包面积. 首先,我们要注意将题目中给出的角度转换成弧度,还要记得取相反数,不然调死你. 这段代码可以与旋转函数放在一起: inline Point Rotate(Vector A,double deg) { register double rad=d

三角剖分求多边形面积的交 HDU3060

1 //三角剖分求多边形面积的交 HDU3060 2 3 #include <iostream> 4 #include <cstdio> 5 #include <cstring> 6 #include <stack> 7 #include <queue> 8 #include <cmath> 9 #include <algorithm> 10 using namespace std; 11 12 const int max

poj 1654 Area(求多边形面积)

题意:从原点出发向八个方向走,所给数字串每个数字代表一个方向,终点与原点连线,求所得多边形面积: 思路:(性质)共起点的两向量叉积的一半为两向量围成三角形的面积.以此计算每条边首尾两个向量的叉积,求和,除二: #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const dou