1069: [SCOI2007]最大土地面积
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3475 Solved: 1385
[ Submit][ Status][ Discuss]
Description
在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成
的多边形面积最大。
Input
第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。
Output
最大的多边形面积,答案精确到小数点后3位。
Sample Input
5
0 0
1 0
1 1
0 1
0.5 0.5
0 0
1 0
1 1
0 1
0.5 0.5
Sample Output
1.000
HINT
数据范围 n<=2000, |x|,|y|<=100000
Source
凸包问题的一个拓展,经分析可知,这四个点一定在凸包上,具体证明就不多说了。。
剩下的就是枚举一条对角线就可以了,这里便是旋转卡壳的奇效了,具体分析见:http://blog.csdn.net/hanchengxi/article/details/8639476
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 1000000000
#define mod 1000000007
#define maxn 1000010
#define lowbit(x) (x&-x)
#define eps 1e-10
struct node
{
double x,y;
}a[maxn],st,q[maxn];
double cross(node a,node b,node c)
{
return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
}
bool comp(node a,node b)
{
if(cross(a,b,st)>0)
return 1;
if(cross(a,b,st)==0 && fabs(a.x-st.x)<fabs(b.x-st.x))
return 1;
return 0;
}
int main(void)
{
double ans=0;
int n,i,top,t1,t2,j;
scanf("%d",&n);
st.x=st.y=inf;
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&a[i].x,&a[i].y);
if(a[i].y<st.y || a[i].y==st.y && a[i].x<st.x)
st=a[i];
}
sort(a+1,a+n+1,comp);
q[1]=a[1];q[2]=a[2];top=2;
for(i=3;i<=n;i++)
{
while(top>1 && cross(q[top-1],a[i],q[top])>=0)
top--;
q[++top]=a[i];
}
for(i=1;i<=top;i++)
{
t2=i%top+1;//枚举的两个三角形定点
t1=(i+2)%top+1;
for(j=i+2;j<=top;j++)//枚举三角形对角线
{
while(cross(q[t1+1],q[i],q[j])>=cross(q[t1],q[i],q[j]))
t1=t1%top+1;
while(cross(q[i],q[t2+1],q[j])>=cross(q[i],q[t2],q[j]))
t2=t2%top+1;
ans=max(ans,(cross(q[t1],q[i],q[j])+cross(q[i],q[t2],q[j]))/2);
}
}
printf("%.3f\n",ans);
return 0;
}