二维凸包的板子

二维凸包的板子

感觉没什么可说的,码风抄的孔老师的。

#include <cstdio>
#include <algorithm>
#include <cmath>
const int N=1e4+10;
#define Point Vector
const double eps=1e-8;
bool cmp(double a,double b){return fabs(a-b)<eps;}
struct Vector
{
    double x,y;
    Vector(){}
    Vector(double x,double y){this->x=x,this->y=y;}
    bool friend operator <(Vector n1,Vector n2){return cmp(n1.x,n2.x)?n1.y<n2.y:n1.x<n2.x;}
    Vector friend operator -(Vector n1,Vector n2){return Vector(n1.x-n2.x,n1.y-n2.y);}
}pot[N],s[N];
int n,tot;
double Cross(Point n1,Point n2){return n1.x*n2.y-n1.y*n2.x;}
double Dis(Point n1,Point n2){return sqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y));}
void push(Point n)
{
    while(tot>1&&Cross(s[tot]-s[tot-1],n-s[tot])<0) --tot;
    s[++tot]=n;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lf%lf",&pot[i].x,&pot[i].y);
    std::sort(pot+1,pot+1+n);
    s[++tot]=pot[1];
    for(int i=2;i<=n;i++) push(pot[i]);
    for(int i=n-1;i;i--) push(pot[i]);
    double ans=Dis(s[1],s[tot]);
    for(int i=2;i<=tot;i++) ans+=Dis(s[i],s[i-1]);
    printf("%.2lf\n",ans);
    return 0;
}


2018.12.27

原文地址:https://www.cnblogs.com/ppprseter/p/10185369.html

时间: 2024-10-02 02:21:45

二维凸包的板子的相关文章

计算几何 二维凸包问题 Andrew算法

凸包:把给定点包围在内部的.面积最小的凸多边形. Andrew算法是Graham算法的变种,速度更快稳定性也更好. 首先把所有点排序,按照第一关键字x第二关键字y从小到大排序,删除重复点后得到点序列P1...Pn. 1)把P1,P2放入凸包中,凸包中的点使用栈存储 2)从p3开始,当下一个点在凸包当前前进方向(即直线p1p2)左边的时候继续: 3)否则依次删除最近加入凸包的点,直到新点在左边. 如图,新点P18在当前前进方向P10P15的右边(使用叉积判断),因此需要从凸包上删除点P15和P10

使用Graham扫描法求二维凸包的一个程序

1 #include "includeall.h" 2 #include "Link.class.h" 3 4 int RightOrLeft(float x1,float y1,float x2,float y2,float x3,float y3)//判断第三个点在前两个点连成的直线的哪个位置,-1 左边,0,直线上,1 右边 5 { 6 float X=(y3-y1)*(x2-x1)/(y2-y1)+x1; 7 if(X<x3) 8 { 9 return

UVA 10652 Board Wrapping(二维凸包)

传送门 刘汝佳<算法竞赛入门经典>P272例题6包装木板 题意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们抱起来,并计算出木板占整个包装面积的百分比. 输入:t组数据,每组先输入木板个数n,接下来n行,每行x,y,w,h,j.(x,y)是木板中心的坐标,w是宽,h是高,j是顺时针旋转的角度. 木板互不相交. 输出:对于每组数据,输出木板总面积占包装总面积的百分比,保留小数点后1位. 题解:典型的二维凸包问题,理解并调用模板即可. #include <math.h>

二维凸包模板

double cross(Point a,Point b) { return a.x*b.y-a.y*b.x; } double mul(Point p0,Point p1,Point p2) { return cross(p1-p0,p2-p0); } double dis(Point a) { return sqrt(a.x*a.x+a.y*a.y); } bool cmp(Point a,Point b) { if(dcmp(mul(p[0],a,b))==0) return dis(a-

二维凸包

二维凸包模板 p[1010]//输入的点集,res[1010]//输出的点集 int n;//点的个数 int cmp(Point a,Point b)//先对x坐标排序,在比较y坐标 { if(a.x==b.x) return a.y<b.y; return a.x<b.x; } int ConvexHull()//返回凸包顶点数 { sort(p,p+n,cmp); int m=0; for(int i=0;i<=n-1;i++) { while(m>1&&Cr

Luogu 2742 二维凸包

Luogu 2742 二维凸包 使用 \(Andrew\) 算法.将点排序后分别求上下凸壳,用单调栈维护. 利用向量叉积来判断当前方向.若 \(v_1\times v_2<0\) ,说明 \(v_2\) 在 \(v_1\) 的右侧, \(<0\) 为左侧, \(=0\) 说明二者共线. 参考讲解. #include<bits/stdc++.h> using namespace std; #define ll long long #define mp make_pair #defin

【题解】二维凸包

[题解]二维凸包 呵呵呵复习一下这个东西免得做到计算几何连暴力都不会嘤嘤嘤 免得到时候写斜率优化结果凸包不会了嘤嘤嘤 数学走起: \[ \vec{a}=(x_1,y_1),\vec{b}=(x_2,y_2) \shadow_{|\vec{a} \times\vec{b}|}=x_1y_2-x_2y_1 \] 根据右手螺旋定则.\(shadow\)是我乱搞的符号,虽然我搞不懂为什么是这样,但是这个应该和\(\sin(0.5\pi)=1,\sin0=0\)有关,就不纠结了,也比较好记. 遵循\(an

算法模板——计算几何2(二维凸包——Andrew算法)

实现功能:求出二维平面内一对散点的凸包(详见Codevs 1298) 很神奇的算法——先将各个点按坐标排序,然后像我们所知的那样一路左转,求出半边的凸包,然后反过来求另一半的凸包 我以前正是因为总抱着想一步到位的想法,所以每次都跪得很惨(HansBug:事实上这次是我这辈子第一次A掉凸包题) 然后别的没了,就是凸包的基本思想 (顺便输出凸包周长C和面积S,好评如潮哦) 1 type arr=array[0..100005] of longint; 2 var 3 i,j,k,l,m,n,m1,m

P2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows

题意:n个点,求凸包周长.(纯板子QAQ) 定义 凸包:用最小的凸多边形将n个点围在里面的图形为凸包 前置 向量:点积:(a,b) (c,d)=(a*c,b*d) =|(a,b)|*|(c,d)|*cos<(a,b),(c,d)>; 叉积:(a,b) (c,d)=a*d-b*c=|(a,b)|*|(c,d)|*sin<(a,b),(c,d)>;  几何意义:以(a,b)(c,d)两向量作平行四边形,它俩的叉积为其面积 故有三角形面积=$\large{\frac{1}{2}*|(a,