poj2079(一堆點找出最大的三角形)
阿新 • • 發佈:2019-01-30
題意:
給出n個二維座標點,找出三個點,它們組成的三角形面積最大。
思路:
首先,面積最大的三角形的三個點一定在凸包上,我們先求所有點的凸包,然後選擇一個邊i、j,列舉k,找到一個最大的面積,然後定下i,列舉j和k,找到最大的面積。
pojG++是坑!
程式碼:
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<set> #include<vector> #include<string> #define EPS 1e-10 #define MAXN 50100 using namespace std; struct point { double x,y; point(){} point(double tx,double ty):x(tx),y(ty){} point(const point &tt) { x=tt.x; y=tt.y; } }; point data[MAXN]; point convex[MAXN]; point start(0,0); inline double cross(const point &p1,const point &p2,const point &q1,const point &q2) { return (q2.y-q1.y)*(p2.x-p1.x)-(q2.x-q1.x)*(p2.y-p1.y); } inline bool cmp1(const point &a,const point &b) { if(a.y==b.y) return a.x<b.x; return a.y<b.y; } inline bool cmp2(const point &a,const point &b)//逆時針排序 { point origin; origin=start; return cross(origin,a,origin,b)>0||(cross(origin,a,origin,b)==0&&fabs(a.x)<fabs(b.x)); } inline void convex_hull(int &cnt,int n) { sort(data,data+n,cmp1); start=data[0]; sort(data+1,data+n,cmp2); convex[cnt++]=start; convex[cnt++]=data[1]; for(int i=2;i<n;++i) { while(cnt>=2&&cross(convex[cnt-2],convex[cnt-1],convex[cnt-1],data[i])<=0) --cnt; convex[cnt++]=data[i]; } } inline double rotating_calipers(int n) { int j=1,k=0; double area=0; for(int i=0;i<n;++i) { j=(i+1)%n; k=(j+1)%n; while(fabs(cross(convex[i],convex[j],convex[i],convex[k]))< fabs(cross(convex[i],convex[j],convex[i],convex[(k+1)%n]))) k=(k+1)%n; while(j!=i&&k!=i) { area=max(area,fabs(cross(convex[i],convex[j],convex[i],convex[k]))); while(fabs(cross(convex[i],convex[j],convex[i],convex[k]))< fabs(cross(convex[i],convex[j],convex[i],convex[(k+1)%n]))) k=(k+1)%n; j=(j+1)%n; } } return area; } int main() { int n; while(scanf("%d",&n)!=EOF) { if(n==-1) break; for(int i=0;i<n;i++) scanf("%lf%lf",&data[i].x,&data[i].y); if(n<=2) { printf("0.00\n"); continue; } int cnt=0; convex_hull(cnt,n); if(cnt<=2) printf("0.00\n"); else { if(cnt==3) printf("%.2lf\n",fabs(cross(convex[0],convex[1],convex[0],convex[2]))/2); else printf("%.2lf\n",rotating_calipers(cnt)/2); } } return 0; }