1. 程式人生 > >poj2079(一堆點找出最大的三角形)

poj2079(一堆點找出最大的三角形)

題意:

給出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;
}