码迷,mamicode.com
首页 > 其他好文 > 详细

[poj] 2079 Triangle || 旋转卡壳

时间:2018-01-01 23:39:33      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:return   point   abs   while   down   ref   amp   ==   problem   

原题

给出n个点,求最大面积三角形。


最大面积三角形一定在凸包上,所以先Graham求凸包。在凸包上旋转卡壳(固定一个定点,旋转一个,在旋转另一个)。
O(n^2)

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100010
#define eps 1e-8
using namespace std;
int n,m,top,per[N];
double x,y,area;
struct point
{
    double x,y;
    point() : x(0),y(0) {}
    point(double _x,double _y) : x(_x),y(_y) {}
    bool operator < (const point &b) const
    {
        return x<b.x || (x==b.x && y<b.y);
    }
    point operator + (const point &b) const
    {
        return point(x+b.x,y+b.y);
    }
    point operator - (const point &b) const
    {
        return point(x-b.x,y-b.y);
    }
    point operator * (const double &b) const
    {
        return point(x*b,y*b);
    }
    double operator * (const point &b) const
    {
        return x*b.y-b.x*y;
    }
    double norm()
    {
        return x*x+y*y;
    }
}p[N],q[N];

double ABS(double x) { return x>=0?x:-x; }

int dcmp(double x)
{
    if (x<=eps && x>=-eps) return 0;
    return x>0?1:-1;
}

bool cmp(int i,int j)
{
    int d=(p[i]-p[1])*(p[j]-p[1]);
    if (d!=0) return d<0;
    return (p[i]-p[1]).norm()>(p[j]-p[1]).norm();
}

void Graham()
{
    sort(p+1,p+n+1);
    top=0;
    for (int i=1;i<=n;i++)
    {
        while (top>1 && dcmp((q[top]-q[top-1])*(p[i]-q[top-1]))<=0)
            --top;
        q[++top]=p[i];
    }
    int k=top;
    for (int i=n-1;i>=1;i--)
    {
        while (top>k && dcmp((q[top]-q[top-1])*(p[i]-q[top-1]))<=0)
            --top;
        q[++top]=p[i];
    }
    if (n>1) --top;
}

double rotating()
{
    if (top<=2) return 0;
    if (top==3) return ABS(((q[2]-q[1])*(q[3]-q[1]))/2.0);
    double ans=0;
    for (int i=1;i<=top;i++)
    {
    int j=i%top+1;
    int k=j%top+1;
    while (dcmp(ABS((q[i]-q[j])*(q[i]-q[k]))-ABS((q[i]-q[j])*(q[i]-q[k%top+1])))<0)
        k=k%top+1;
    while (i!=j && j!=k && i!=k)
    {
        ans=max(ans,ABS(((q[i]-q[j])*(q[i]-q[k]))/2.0));
        while(dcmp(ABS((q[i]-q[j])*(q[i]-q[k]))-ABS((q[i]-q[j])*(q[i]-q[k%top+1])))<0)
        k=k%top+1;
        j=j%top+1;
    }
    }
    return ans;
}

int main()
{
    while (~scanf("%d",&n))
    {
    if (n==-1) break;
    top=0;
    for (int i=1;i<=n;i++)
        scanf("%lf%lf",&p[i].x,&p[i].y);
    Graham();
    area=rotating();
    printf("%.2lf\n",area);
    }
    return 0;
}

[poj] 2079 Triangle || 旋转卡壳

标签:return   point   abs   while   down   ref   amp   ==   problem   

原文地址:https://www.cnblogs.com/mrha/p/8168890.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!