poj2079凸包求最大三角形面积

来源:互联网 发布:单板滑雪u型池具体数据 编辑:程序博客网 时间:2024/05/22 03:25

一开始参照书上的写法些了一个,后来理解了一下自己写了一个

自写的:

#include <cmath>#include <algorithm>#include <iostream>using namespace std;#define MAXN 50005struct Point{    int x, y;    bool operator < (const Point& _P) const    {        return y<_P.y||(y==_P.y&&x<_P.x);    };}point[MAXN],stack[MAXN];int cross(Point a,Point b,Point o)      {    return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);}double area(Point o,Point a,Point b){int ax=a.x-o.x;int bx=b.x-o.x;int ay=a.y-o.y;int by=b.y-o.y;return abs(bx*ay-ax*by)*1.0/2.0;}//graham()求凸包 void convex_hull(Point *p,Point *stack,int n,int &len){    sort(p, p+n);    stack[0]=p[0];    stack[1]=p[1];    int top=1;    for(int i=2;i<n;i++)    {        while(top>0&&cross(stack[top],p[i],stack[top-1])<=0)            top--;        stack[++top]=p[i];    }    int tmp=top;    for(int i=n-2;i>=0;i--)    {        while(top>tmp&&cross(stack[top],p[i],stack[top-1])<=0)            top--;        stack[++top]=p[i];    }    len=top;    }int dist(Point a,Point b){    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);}//旋转卡壳 double rotating_calipers(Point *stack,int n){    int q=1;double ans=0;    stack[n]=stack[0];   /* for(int z=0;z<n;z++)    cout<<stack[z].x<<"  "<<stack[z].y<<endl;    system("pause");*/    for(int p=0;p<n;p++)    {int j=(p+1)%n;int k=(j+1)%n;//卡壳确定两个点求面积,而求距离就只用确定一个点只用一个while         while(area(stack[p],stack[j],stack[k])<area(stack[p],stack[j],stack[(k+1)%n]))            k=(k+1)%n;    if(k==p)continue;    int kk=(k+1)%n;    while(j!=kk && k!=p)    {ans=max(ans,area(stack[p],stack[j],stack[k]));while(k!=p && area(stack[p],stack[j],stack[k])<area(stack[p],stack[j],stack[(k+1)%n]))k=(k+1)%n;j=(j+1)%n;}                }    return ans; }int main(){    int n, len;    while(scanf("%d",&n)!=EOF && n!=-1)    {        for(int i = 0;i < n;i++)        {            scanf("%d %d",&point[i].x,&point[i].y);        }        convex_hull(point,stack,n,len);        printf("%.2lf\n",rotating_calipers(stack,len));    }    return 0;}

书上的介绍

#include<iostream>#include<algorithm>#include<cmath> #define N 50005using namespace std;struct node{int x,y;}dd[N];int n,stak[N],top,top1;bool cmp(const node &a,const node &b){return a.x<b.x||(a.x==b.x && a.y<b.y);} bool judge_right(int o,int a,int b){int ax=dd[a].x-dd[o].x;int bx=dd[b].x-dd[o].x;int ay=dd[a].y-dd[o].y;int by=dd[b].y-dd[o].y;return (__int64)bx*ay>(__int64)ax*by;}double area(int o,int a,int b){int ax=dd[a].x-dd[o].x;int bx=dd[b].x-dd[o].x;int ay=dd[a].y-dd[o].y;int by=dd[b].y-dd[o].y;return abs(bx*ay-ax*by)*1.0/2.0;}void build_map(){int i;top=0;sort(dd,dd+n,cmp);stak[top++]=0;stak[top++]=1;for(i=2;i<n;i++){stak[top++]=i;while(top>=3){if(judge_right(stak[top-3],stak[top-2],stak[top-1]))break;stak[top-2]=stak[top-1];top--;}}top1=top;stak[top++]=n-2;for(i=n-3;i>=0;i--){stak[top++]=i;while(top-top1>=2){if(judge_right(stak[top-3],stak[top-2],stak[top-1]))break;stak[top-2]=stak[top-1];top--;}}top--;}int main(){int i,j,k;while(scanf("%d",&n)!=EOF && n!=-1){for(i=0;i<n;i++)scanf("%d%d",&dd[i].x,&dd[i].y);build_map();double ans=0;/*for(int i=0;i<top;i++)cout<<dd[stak[i]].x<<"   "<<dd[stak[i]].y<<endl;*/for(i=0;i<top;i++){j=(i+1)%top;k=(j+1)%top;while(k!=i && area(stak[i],stak[j],stak[k])<area(stak[i],stak[j],stak[(k+1)%top]))k=(k+1)%top;if(k==i)continue;int kk=(k+1)%top;while(j!=kk && k!=i){ans=max(ans,area(stak[i],stak[j],stak[k]));while(k!=i && area(stak[i],stak[j],stak[k])<area(stak[i],stak[j],stak[(k+1)%top]))k=(k+1)%top;j=(j+1)%top;}}printf("%.2lf\n",ans);}}



原创粉丝点击