计算几何——最大三角形【HDU2202】

来源:互联网 发布:如何查看电脑的端口号 编辑:程序博客网 时间:2024/06/04 18:22

题目描述

老师在计算几何这门课上给Eddy布置了一道题目,题目是这样的:给定二维的平面上n个不同的点,要求在这些点里寻找三个点,使他们构成的三角形拥有的面积最大。
Eddy对这道题目百思不得其解,想不通用什么方法来解决,因此他找到了聪明的你,请你帮他解决这个题目。


输入格式

输入数据包含多组测试用例,每个测试用例的第一行包含一个整数n,表示一共有n个互不相同的点,接下来的n行每行包含2个整数xi,yi,表示平面上第i个点的x与y坐标。你可以认为:3 <= n <= 50000 而且 -10000 <= xi, yi <= 10000.


输出格式

对于每一组测试数据,请输出构成的最大的三角形的面积,结果保留两位小数。
每组输出占一行。


样例输入

3
3 4
2 6
3 7
6
2 6
3 9
2 0
8 0
6 6
7 7


样例输出

1.50
27.00


先跑出凸包
然后再枚举一点,对剩下的两点,类似旋转卡壳一样的方法处理。

大概,这是计算几何中比较基础的问题吧qwq
唔,注意题目有多组数据输入输出

#include<cstdio>#include<cstdlib>#include<algorithm>#define maxn 50005using namespace std;struct Point{    int x,y;    friend Point operator - (Point a,Point b){return (Point){a.x-b.x,a.y-b.y};}}node[maxn],S[maxn];bool cmp(Point a,Point b){    if(a.x<b.x) return true;    if(a.x==b.x && a.y<b.y) return true;    return false;}int Cross(Point a,Point b){return (a.x*b.y-a.y*b.x);}int main(){    int n;    while(scanf("%d",&n)!=EOF){        for(int i=1;i<=n;i++)            scanf("%d%d",&node[i].x,&node[i].y);        sort(node+1,node+1+n,cmp);        S[0]=node[0]=node[1];        int cnt=0;        for(int i=1;i<=n;i++){            while(cnt>1 && Cross(S[cnt]-S[cnt-1],node[i]-S[cnt-1])<=0)                cnt--;            S[++cnt]=node[i];        }        int k=cnt;        for(int i=n-1;i>=1;i--){            while(cnt>k && Cross(S[cnt]-S[cnt-1],node[i]-S[cnt-1])<=0)                cnt--;            S[++cnt]=node[i];        }        int p1=3,p2=2,ans=abs(Cross(S[2]-S[1],S[3]-S[1]));        bool flag;        for(int i=1;i<cnt;i++){            if(i==p2) p2++;            if(p2==cnt) p2=1;            do{                flag=false;                while(abs(Cross(S[p1]-S[i],S[p2]-S[i]))<=abs(Cross(S[p1+1]-S[i],S[p2]-S[i]))){                    p1++;if(p1==cnt) p1=1;                    flag=true;                }                ans=max(ans,abs(Cross(S[p1]-S[i],S[p2]-S[i])));                while(abs(Cross(S[p1]-S[i],S[p2]-S[i]))<=abs(Cross(S[p1]-S[i],S[p2+1]-S[i]))){                    p2++;if(p2==cnt) p2=1;                    flag=true;                }                ans=max(ans,abs(Cross(S[p1]-S[i],S[p2]-S[i])));            }while(flag);        }        printf("%.2f\n",ans*0.5);    }    return 0;}
0 0