您的位置:首页 > 其它

HDU 3934 Summer holiday(凸包内接最大三角形)

2012-10-31 17:51 417 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3934

题意:给出n个点,从中找出三个点使得面积最大。

思路:旋转卡壳模板题:首先求凸包,在旋转求最大面积。

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
using namespace std;

struct point
{
double x,y;

point(){}
point(double _x,double _y)
{
x=_x;
y=_y;
}

void get()
{
scanf("%lf%lf",&x,&y);
}
};

const double EPS=1e-8;
const int MAX=1000005;
point p[MAX],q[MAX];
int n,m;

int DB(double x)
{
if(x>EPS) return 1;
if(x<-EPS) return -1;
return 0;
}

double Dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

//判断p在向量ab的哪一侧
//右侧:返回正值
//左侧:返回负值
//在向量ab上返回0
double cross(point a,point b,point p)
{
return (b.x-a.x)*(p.y-a.y)-(b.y-a.y)*(p.x-a.x);
}

int cmp(point a,point b)
{
double x=Dis(a,p[0]),y=Dis(b,p[0]);
int flag=DB(cross(p[0],a,b));
if(flag) return flag==1;
return DB(x-y)<=0;
}

void Graham(point p[],int n,point q[],int &m)
{
point temp;
int i,k=0,a,b;
for(i=1;i<n;i++)
{
a=DB(p[i].y-p[k].y);
b=DB(p[i].x-p[k].x);
if(a==-1||!a&&b==-1) k=i;
}
if(k!=0) temp=p[0],p[0]=p[k],p[k]=temp;
sort(p+1,p+n,cmp);
q[0]=p[0];
q[1]=p[1];
p
=p[0];
m=2;
for(i=2;i<=n;i++)
{
while(m>1&&DB(cross(q[m-2],q[m-1],p[i]))<=0) m--;
q[m++]=p[i];
}
m--;
}

double calMaxArea(point q[],int n)
{
if(n<3) return 0;
double ans=0,temp;
int t1=1,t2=2,i;
q
=q[0];
for(i=0;i<n;i++)
{
while(DB(cross(q[t2+1],q[i],q[t1])-(temp=cross(q[t2],q[i],q[t1])))==1)
t2=(++t2)%n;
if(DB(temp-ans)==1) ans=temp;
while(DB(cross(q[t2],q[i],q[t1+1])-(temp=cross(q[t2],q[i],q[t1])))==1)
t1=(++t1)%n;
if(DB(temp-ans)==1) ans=temp;
}
return ans/2;
}

int main()
{
while(scanf("%d",&n)!=-1)
{
int i;
for(i=0;i<n;i++) p[i].get();
Graham(p,n,q,m);
double ans=calMaxArea(q,m);
printf("%.2lf\n",ans);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: