HDU 2202 最大三角形(凸包)

Problem Description
老师在计算几何这门课上给Eddy布置了一道题目,题目是这样的:给定二维的平面上n个不同的点,要求在这些点里寻找三个点,使他们构成的三角形拥有的面积最大。
Eddy对这道题目百思不得其解,想不通用什么方法来解决,因此他找到了聪明的你,请你帮他解决这个题目。
 
Input
输入数据包含多组测试用例,每个测试用例的第一行包含一个整数n,表示一共有n个互不相同的点,接下来的n行每行包含2个整数xi,yi,表示平面上第i个点的x与y坐标。你可以认为:3 <= n <= 50000 而且 -10000 <= xi, yi <= 10000.
 
Output
对于每一组测试数据,请输出构成的最大的三角形的面积,结果保留两位小数。
每组输出占一行。
 
Sample
Sample Input
3
3 4
2 6
3 7
6
2 6
3 9
2 0
8 0
6 6
7 7
 

Sample Output
1.50
27.00

题意:

  求最大的三角形面积。

思路

  做出凸包,遍历即可,主要是旋转卡壳不会用,恰好后台数据没有那么大N^3没有T。三角形面积可以用两向量叉乘/2求出。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define PI 3.1415926535
using namespace std;
struct node
{
    int x,y;
};
node vex[100000];//存入的所有的点
node stackk[100000];//凸包中所有的点
int xx,yy;
bool cmp1(node a,node b)
{
    if(a.y==b.y)
        return a.x<b.x;
    else
        return a.y<b.y;
}
double cross(node a,node b,node c)//计算叉积
{
    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double dis(node a,node b)//计算距离
{
    return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y));
}
bool cmp2(node a,node b)//极角排序另一种方法,速度快
{
    if(atan2(a.y-yy,a.x-xx)!=atan2(b.y-yy,b.x-xx))
        return (atan2(a.y-yy,a.x-xx))<(atan2(b.y-yy,b.x-xx));
    return a.x<b.x;
}
bool cmp(node a,node b)//极角排序
{
    int m=cross(vex[0],a,b);
    if(m>0)
        return 1;
    else if(m==0&&dis(vex[0],a)-dis(vex[0],b)<=0)
        return 1;
    else return 0;
    /*if(m==0)
        return dis(vex[0],a)-dis(vex[0],b)<=0?true:false;
    else
        return m>0?true:false;*/
}
int main()
{
    int t,L;
    while(~scanf("%d",&t))
    {
        int i;
        for(i=0; i<t; i++)
        {
            scanf("%d%d",&vex[i].x,&vex[i].y);
        }
        memset(stackk,0,sizeof(stackk));
        sort(vex,vex+t,cmp1);
        stackk[0]=vex[0];
        xx=stackk[0].x;
        yy=stackk[0].y;
        sort(vex+1,vex+t,cmp2);
        stackk[1]=vex[1];//将凸包中的前两个点存入凸包的结构体中
        int top=1;//最后凸包中拥有点的个数*/
        for(i=2; i<t; i++)
        {
            while(i>=1&&cross(stackk[top-1],stackk[top],vex[i])<0)
                top--;
            stackk[++top]=vex[i];
        }
       double s=0;//三角形的面积可以由向量叉乘/2
        for(int i = 0; i<=top; i++)
            for(int j = i+1; j<=top; j++)
                for(int k = j+1; k<=top; k++)
                    s = max(s,cross(stackk[i],stackk[j],stackk[k]));
        printf("%.2lf
",s/2.0);

    }
}
原文地址:https://www.cnblogs.com/aiguona/p/7249063.html