凸包

来源:互联网 发布:after school知乎 编辑:程序博客网 时间:2024/04/29 06:24

初学凸包,到百度百科上面搜了一下,发现还是很好理解的。。。。看着上面的代码敲了一遍,,,发现上面的代码有BUG。。。。

下面是自己写的:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <algorithm>#include <map>#include <vector>#include <cmath>using namespace std;int n,top;typedef struct{    double x;    double y;} POINT;POINT result[102];POINT g[102];double Multi(POINT c,POINT a,POINT b){    return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x);}double Dis(POINT a,POINT b){    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}bool cmp(const POINT a,const POINT b){    double m = Multi(g[0],a,b);    if(m < 0)return 0;    else if(m == 0 && Dis(g[0],a) < Dis(g[0],b))return 0;    else return 1;}void Tubao(){    result[0].x = g[0].x;    result[0].y = g[0].y;    result[1].x = g[1].x;    result[1].y = g[1].y;    top = 1;    for(int i = 2; i <= n; i++)    {        while(Multi(result[top - 1],result[top],g[i]) <= 0 && top > 1)            top --;        top ++;        result[top].x = g[i].x;        result[top].y = g[i].y;    }}int main(){//    freopen("in.txt","r",stdin);    while(~scanf("%d",&n))    {        int p ;        double dx,dy = 100000;        for(int i = 0; i < n; i++)        {            scanf("%lf%lf",&g[i].x,&g[i].y);            if(g[i].y < dy)            {                dy = g[i].y;                dx = g[i].x;                p = i;            }            else if(g[i].y == dy && g[i].x < dx)            {                dx = g[i].x;                p = i;            }        }        swap(g[0].x,g[p].x);        swap(g[0].y,g[p].y);        sort(g + 1,g + n,cmp);        g[n].x = g[0].x;        g[n].y = g[0].y;        Tubao();        double len = 0;        for(int i = 0; i < top; i ++)        {            len += Dis(result[i],result[i+1]);        }        printf("len = %.2lf\n",len);    }    return 0;}


自己想了个测例:

60 -12 0.51 1-1 0.51 01 0.5
80 -20 22 00.5 0-0.5 0.2-2 0-1 01 0

跑出来是:len = 7.48;len = 11.31


而用百度百科上面的跑出来却是: len = 7.51;len= 11.72

(是对是错把路径打出来就知道。。。。)

下面是百度上面的代码(代码一):

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <algorithm>#include <map>#include <vector>#include <cmath>using namespace std;typedef struct{    double x;    double y;} POINT;POINT result[102];//保存凸包上的点,相当于所说的栈SPOINT a[102];int n,top;double Distance(POINT p1,POINT p2)//两点间的距离{    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));}double Multiply(POINT p1,POINT p2,POINT p3)//叉积{    return((p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x));}int Compare(const void*p1,const void*p2)//根据p0->p1的极值和p0->p2的极值进行比较,如果极值相同则用距离长度比较{    POINT *p3,*p4;    double m;    p3=(POINT*)p1;    p4=(POINT*)p2;    m=Multiply(a[0],*p3,*p4);    if(m<0)return 1;    else if(m==0&&(Distance(a[0],*p3)<Distance(a[0],*p4)))        return 1;    else return -1;}//寻找凸包的过程,p0,p1,p2..的寻找过程在下面main中进行了void Tubao(){    int i;    result[0].x=a[0].x;    result[0].y=a[0].y;    result[1].x=a[1].x;    result[1].y=a[1].y;    result[2].x=a[2].x;    result[2].y=a[2].y;    top=2;    for(i=3; i<=n; i++)    {        while(Multiply(result[top-1],result[top],a[i])<=0&&top>2)            top--;        result[top+1].x=a[i].x;        result[top+1].y=a[i].y;        top++;    }}int main(){//    freopen("in.txt","r",stdin);    int i,p;    double px,py,len,temp;    while(scanf("%d",&n)!=EOF)    {        for(i=0; i<n; i++)            scanf("%lf%lf",&a[i].x,&a[i].y);        if(n==1)        {            printf("0.00/n");            continue;        }        else if(n==2)        {            printf("%.2lf/n",Distance(a[0],a[1]));            continue;        }//这里的目的好像是找出y坐标最小的点,之后把他定义为P0        py=-1;                  /************* 排序这有问题 *************/        for(i=0; i<n; i++)        {            if(py==-1||a[i].y<py)            {                px=a[i].x;                py=a[i].y;                p=i;            }            else if(a[i].y==py&&a[i].x<px)            {                px=a[i].x;                py=a[i].y;                p=i;            }        }//swap(a[0],a[p])        temp=a[0].x;        a[0].x=a[p].x;        a[p].x=temp;        temp=a[0].y;        a[0].y=a[p].y;        a[p].y=temp;//用叉乘来实现排序的比较        qsort(&a[1],n-1,sizeof(double)*2,Compare);        a[n].x=a[0].x;        a[n].y=a[0].y;//调用tubao()        Tubao();        len=0.0;        for(i=0; i<top; i++)        {            len=len+Distance(result[i],result[i+1]);        }        printf("%.2lf\n",len);    }    return 0;}

分析:上面的代码之所以错是因为在排序的时候没有处理好,,,另外在找凸包顶点的时候也有问题(函数Tubao())。。。。

(看来以后找代码看的注意了。。。)

0 0
原创粉丝点击