二维凸包

二维凸包模板

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&&Cross(res[m-1]-res[m-2],p[i]-res[m-2])<=0)
            m--;
        res[m++]=p[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--)
    {
        while(m>k&&Cross(res[m-1]-res[m-2],p[i]-res[m-2])<=0)
            m--;
        res[m++]=p[i];
    }
    if(n>1)//起始点重复
        m--;
    return m;
}

for(int i=0;i<=m-2;i++)//求凸包的长度
            sum+=length(res[i],res[i+1]);
        sum+=length(res[0],res[m-1]);

poj 1113

Description

Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King‘s castle. The King was so greedy, that he would not listen to his Architect‘s proposals to build a beautiful brick wall with a perfect shape and nice tall
towers. Instead, he ordered to build the wall around the whole castle using the least amount of stone and labor, but demanded that the wall should not come closer to the castle than a certain distance. If the King finds that the Architect has used more resources
to build the wall than it was absolutely necessary to satisfy those requirements, then the Architect will loose his head. Moreover, he demanded Architect to introduce at once a plan of the wall listing the exact amount of resources that are needed to build
the wall.

Your task is to help poor Architect to save his head, by writing a program that will find the minimum possible length of the wall that he could build around the castle to satisfy King‘s requirements.

The task is somewhat simplified by the fact, that the King‘s castle has a polygonal shape and is situated on a flat ground. The Architect has already established a Cartesian coordinate system and has precisely measured the coordinates of all castle‘s vertices
in feet.

Input

The first line of the input file contains two integer numbers N and L separated by a space. N (3 <= N <= 1000) is the number of vertices in the King‘s castle, and L (1 <= L <= 1000) is the minimal number of feet that King allows for the wall to come close to
the castle.

Next N lines describe coordinates of castle‘s vertices in a clockwise order. Each line contains two integer numbers Xi and Yi separated by a space (-10000 <= Xi, Yi <= 10000) that represent the coordinates of ith vertex. All vertices are different and the sides
of the castle do not intersect anywhere except for vertices.

Output

Write to the output file the single number that represents the minimal possible length of the wall in feet that could be built around the castle to satisfy King‘s requirements. You must present the integer number of feet to the King, because the floating numbers
are not invented yet. However, you must round the result in such a way, that it is accurate to 8 inches (1 foot is equal to 12 inches), since the King will not tolerate larger error in the estimates.

Sample Input

9 100
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200

Sample Output

1628
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<string>
#include<algorithm>
#define LL long long
#define inf 0x3f3f3f3f
using namespace std;
const double pi=atan(1.0)*4;
struct Point
{
    double x;
    double y;
}p[1010],res[1010];
int n;
typedef Point Vector;
Vector operator - (Point a,Point b) {return Vector{a.x-b.x,a.y-b.y};}
double Cross(Vector a,Vector b)//向量a,b的叉积,在二维坐标系下是一个数
{
    return a.x*b.y-a.y*b.x;
}
int cmp(Point a,Point b)
{
    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&&Cross(res[m-1]-res[m-2],p[i]-res[m-2])<=0)
            m--;
        res[m++]=p[i];
    }
    int k=m;
    for(int i=n-2;i>=0;i--)
    {
        while(m>k&&Cross(res[m-1]-res[m-2],p[i]-res[m-2])<=0)
            m--;
        res[m++]=p[i];
    }
    if(n>1)//起始点重复
        m--;
    return m;
}
double length(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
        int l;
        cin>>n>>l;
        for(int i=0;i<=n-1;i++)
            cin>>p[i].x>>p[i].y;
        int m=ConvexHull();
        double sum=0;
        for(int i=0;i<=m-2;i++)
            sum+=length(res[i],res[i+1]);
        sum+=length(res[0],res[m-1]);
        sum+=2*pi*l;
        printf("%.0lf\n",sum);
    return 0;
}

时间: 2024-08-11 03:32:48

二维凸包的相关文章

计算几何 二维凸包问题 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-

二维凸包的板子

二维凸包的板子 感觉没什么可说的,码风抄的孔老师的. #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()

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

LightOJ 1203--Guarding Bananas(二维凸包+内角计算)

1203 - Guarding Bananas    PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 32 MB Once there was a lazy monkey in a forest. But he loved banana too much. One day there was a storm in the jungle and all the bananas fell from the tr