您的位置:首页 > 其它

bzoj1069 [SCOI2007]最大土地面积 旋转卡壳

2018-01-04 16:12 495 查看

1069: [SCOI2007]最大土地面积

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 3767  Solved: 1501
[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

Sample Output

1.000

HINT

 

数据范围 n<=2000, |x|,|y|<=100000

 

 先求凸包,然后n^2枚举对角线,用旋转卡壳去找位于对角线两侧且到对角线距离最大的两点构成2个三角形,2个三角形面积和就是四边形面积

#include<bits/stdc++.h>
#define N 2010
using namespace std;
int n,tp;
struct P{
double x,y;
bool operator < (const P &b)const{
return x==b.x?y<b.y:x<b.x;
}
P operator - (const P &b)const{
return (P){x-b.x,y-b.y};
}
}a
,s
;
double crs(P a,P b){return a.x*b.y-a.y*b.x;}
void getbag(){
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
while(tp>1&&crs(a[i]-s[tp-1],s[tp]-s[tp-1])>=0)--tp;
s[++tp]=a[i];
}
int now=tp;
for(int i=n-1;i>=1;i--){
while(tp>now&&crs(a[i]-s[tp-1],s[tp]-s[tp-1])>=0)--tp;
s[++tp]=a[i];
}
if(n>1)--tp;
}

void getans(){
double ans=0;s[tp+1]=s[1];
for(int i=1;i<=tp-2;i++){
int a=i+1,b=(i+2)%tp+1;
for(int j=i+2;j<=tp;j++){
while(a%tp+1!=j&&crs(s[a]-s[i],s[j]-s[i])<crs(s[a+1]-s[i],s[j]-s[i]))a=a%tp+1;
while(b%tp+1!=i&&crs(s[j]-s[i],s[b]-s[i])<crs(s[j]-s[i],s[b+1]-s[i]))b=b%tp+1;
ans=max(ans,(crs(s[a]-s[i],s[j]-s[i])+crs(s[j]-s[i],s[b]-s[i]))/2);
}
}
printf("%.3lf\n",ans);
}

int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
getbag();getans();
return 0;
}

 

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