凸包问题 hdu1392 Surround the Trees

来源:互联网 发布:风险矩阵表怎么看 编辑:程序博客网 时间:2024/06/07 06:30

平面凸包 的 Graham算法(时间复杂度:n*lgn)

需要用到的知识点:

1.向量的叉乘

2.qsort快排//这里有简单讲解http://blog.sina.com.cn/s/blog_5155e8d401009145.html

3.对凸包基本概念的理解

4.Graham算法的认识




Graham 算法的具体实现:


1.找到所有点中y坐标值最小的点,如果有多个,取x值最小的,记为p0

2.以p0为固定点,剩余点分别与p0点连接形成的极角按逆时针排序,如果有极角相同的点,与p0点靠近的点排在前面(qsort)

3.把前三个点依次压入栈中,依次遍历剩下n-3个点,在做一个循环,每次判断当前压入的点与栈顶的两个点形成的角的方向(叉乘),若没有左转,出栈,直到栈中两个点与当前点形成的角的方向,左转。把当前点压入栈中。进行下一个点的判断。

4.最后计算出压入栈中的每个点之间的距离


#include<iostream>#include<stdio.h>#include<cmath>#include<stdlib.h>using namespace std;const int maxint=105;struct point{    int x;    int y;}tree[maxint],stack[maxint];double dist(point p,point q){    return sqrt(double((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y)));}double mult(point  A,point B,point C){    return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);}int cmp(const void * p1,const void * p2){    point * p3, * p4;    p3=(point *)p1;    p4=(point *)p2;    int m=mult(tree[0],*p3, *p4);    if(m<0||(m==0&&dist(tree[0],* p3)>dist(tree[0],*p4)))        return 1;    return -1;}double graham(int n){    int x=tree[0].x;    int y=tree[0].y;    int temp=0;    for(int i=1;i<n;i++)    {        if(tree[i].y<y||(tree[i].y==y&&tree[i].x<x))        {            y=tree[i].y;            x=tree[i].x;            temp=i;        }    }    point mi=tree[0];    tree[0]=tree[temp];    tree[temp]=mi;    qsort(tree+1,n-1,sizeof(point),cmp);    tree[n]=tree[0];    stack[0]=tree[0];    stack[1]=tree[1];    stack[2]=tree[2];    int top=2;    for(int i=3;i<=n;i++)    {        while(mult(stack[top-1],stack[top],tree[i])<0&&top>=2)            --top;        stack[++top]=tree[i];    }    double len=0;    for(int i=0;i<top;i++)       len=len+dist(stack[i],stack[i+1]);    return len;}int main(){    int n;    while(cin>>n)    {         for(int i=0;i<n;i++)        {            cin>>tree[i].x>>tree[i].y;        }        if(n==0)            break;        if(n==1)            cout<<"0.00"<<endl;        if(n==2)             printf ("%.2lf\n", dist(tree[0], tree[1]));        else        {            double len=graham(n);            printf("%.2lf\n",len);        }    }    return 0;}


0 0
原创粉丝点击