hdoj 2202 最大三角形 (凸包)

    技术2026-06-11  0

    题目大意:给定n(3<=n<=50000)个点,求其中任意三个点组成的三角形面积最大,输出该面积.

    思路:求凸包,对凸包中任意三个点进行枚举.

     其中可利用凸包的特点进行剪枝.

    另外给出三点坐标,如何求构成的三角形面积.

    如点(x1,y1),(x2,y2),(x3,y3)

    则S=|(x1*y2+x2*y3+x3*y1-y1*x2-y2*x3-y3*x1)/2|

    可画图,面积为两梯形减另外一梯形.

     

     #include <iostream> #include <cmath> using namespace std; const int Max=50001; struct Point { int x; int y; }; Point p[Max]; int n; int cmp(const void *a,const void *b) { Point *c =(Point *)a; Point *d =(Point *)b; if(c->y==d->y) return c->x-d->x; else return c->y-d->y; } int cross(Point p1,Point p2,Point p3) { return (p3.x-p2.x)*(p1.y-p2.y)-(p3.y-p2.y)*(p1.x-p2.x); } int convex(int s[]) { int i,m,m1; for(m=0,i=0;i<n;i++){ while(m>1 && cross(p[s[m-2]],p[s[m-1]],p[i])>=0) m--; s[m++]=i; } m1=m; for(i=n-2;i>0;i--){ while(m>m1 && cross(p[s[m-2]],p[s[m-1]],p[i])>=0) m--; s[m++]=i; } return m; } /* double dis(Point p1,Point p2) { double d=sqrt(double((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); return d; } double area(Point p1,Point p2,Point p3) { double a=dis(p1,p2); double b=dis(p1,p3); double c=dis(p2,p3); double p=(a+b+c)/2; double s=sqrt(p*(p-a)*(p-b)*(p-c)); return s; } */ double area(int i,int j,int k) { double s=fabs(double(p[i].x*p[j].y+p[j].x*p[k].y+p[k].x*p[i].y- p[i].y*p[j].x-p[j].y*p[k].x-p[k].y*p[i].x)/2); return s; } int main() { int s[Max]; double ans,t,t1; int i,j,k,m; while(scanf("%d",&n)!=EOF) { ans=0; for(i=0;i<n;i++) scanf("%d%d",&p[i].x,&p[i].y); qsort(p,n,sizeof(p[0]),cmp); m=convex(s); for(i=0;i<m-2;i++){ for(j=i+1;j<m-1;j++){ if((k=j+1)<m) t1=area(s[i],s[j],s[k]); if(t1>ans) ans=t1; for(k++;k<m;k++){ t=area(s[i],s[j],s[k]); if(t>ans) ans=t; if(t<t1) break; } } } printf("%.2lf/n",ans); } return 0; } 

    最新回复(0)