凸包入门

来源:互联网 发布:布料运算软件 编辑:程序博客网 时间:2024/06/05 04:56
凸包问题:一组平面上的点,求一个包含所有点的最小的凸多边形。
理解:地面上放置若干固定的木桩,用一根绳子把它们圈起来,并且为凸边形
算法:Graham-Scan,时间复杂度O(nlgn);
算法描述:http://www.cnblogs.com/jbelial/archive/2011/08/05/2128625.html
实例:HDU1392

//Date:   2015.05.31//Time:   46ms//Memory: 1620k#include <cstdio>#include <cmath>#include <algorithm>using namespace std;int n;const int MAXN=100;struct Node{    int x,y;}nodes[MAXN],stacks[MAXN];double Distance(Node a,Node b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double Cross(Node a,Node b,Node c){    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);}bool cmp_Y(const Node &a, const Node &b){    if(a.y==b.y)        return a.x<b.x;    else        return a.y<b.y;}bool cmp_P(const Node &a, const Node &b){    int m=Cross(nodes[0],a,b);    if(m)        return m>0 ? true:false;    else        return Distance(nodes[0],a)-Distance(nodes[0],b)<=0 ? true:false;}double ConvexHull(){    int i,top;    double c;    if(n==1)        return 0;    else if(n==2)        return Distance(nodes[0],nodes[1]);    else{        sort(nodes,nodes+n,cmp_Y);        sort(nodes+1,nodes+n,cmp_P);        stacks[0]=nodes[0];        stacks[1]=nodes[1];        stacks[2]=nodes[2];        top=2;        for(i=3;i<n;i++){            while(Cross(stacks[top-1],stacks[top],nodes[i])<=0)                top--;            stacks[++top]=nodes[i];        }        c=0;        for(i=1;i<=top;i++)            c += Distance(stacks[i-1],stacks[i]);        c += Distance(stacks[top],nodes[0]);        return c;    }}int main(){    int i;    double circumference;    while(scanf("%d",&n),n){        for(i=0;i<n;i++)            scanf("%d%d",&nodes[i].x,&nodes[i].y);        circumference=ConvexHull();        printf("%.2f\n",circumference);    }    return 0;}

0 0
原创粉丝点击