[BZOJ1069][SCOI2007]最大土地面积 凸包+旋转卡壳

1069: [SCOI2007]最大土地面积

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

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define eps 1e-9
using namespace std;
struct point {
double x,y;
bool operator <(const point t) const {
return fabs(t.x-x)>eps?x<t.x:y<t.y;
}
}p[],s[];
point operator -(point t1,point t2) {
return (point){t1.x-t2.x,t1.y-t2.y};
}
double operator *(point t1,point t2) {
return t1.x*t2.y-t2.x*t1.y;
}
int n,top;
void get() {
s[]=p[];
for(int i=;i<=n;i++) {
while(top&&(s[top]-s[top-])*(p[i]-s[top])>=) top--;
s[++top]=p[i];
}
int tmp=top;
for(int i=n-;i>=;i--) {
while(top>tmp&&(s[top]-s[top-])*(p[i]-s[top])>=) top--;
s[++top]=p[i];
}
}
double cnts(point a,point b,point c) {
return fabs((b-a)*(c-a))/;
}
int main() {
double maxn=;
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+,p+n+);
get();
for(int i=;i<top;i++) {
int j=(i+)%top,k=(i+)%top,w=(j+)%top;
while(cnts(s[i],s[j],s[k])<cnts(s[i],s[j],s[k+])) k=(k+)%top;
double ans1=cnts(s[i],s[j],s[k]);
while(cnts(s[i],s[j],s[w])<cnts(s[i],s[j],s[w+])) w=(w+)%top;
double ans2=cnts(s[i],s[j],s[w]);
double ans=;
while(ans1+ans2>ans) {
ans=ans1+ans2;
j=(j+)%top;
while(cnts(s[i],s[j],s[k])<cnts(s[i],s[j],s[k+])) k=(k+)%top;
ans1=cnts(s[i],s[j],s[k]);
while(cnts(s[i],s[j],s[w])<cnts(s[i],s[j],s[w+])) w=(w+)%top;
ans2=cnts(s[i],s[j],s[w]);
}
maxn=max(maxn,ans);
}
printf("%.3lf",maxn);
}
上一篇:基于Jquery的下拉列表控件(个人觉得实用)


下一篇:微信小程序如何提交审核并发布?发布问题:小程序只支持https访问