BZOJ 1069 SCOI2007 最大土地面积

1069: [SCOI2007]最大土地面积

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

 

Source

凸包+旋转卡壳即可

注意叉积不满足交换律

#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
    int x=0;int f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int MAXN=1e6+10;
int n;
struct node{
    double x,y;
}s[MAXN],p[MAXN];
int top=0;
inline node operator + (node n,node m){
    node t;t.x=n.x-m.x;t.y=n.y-m.y;return t;
}
inline node operator - (node n,node m){
    node t;t.x=n.x-m.x;t.y=n.y-m.y;return t;
}
inline double operator * (node n,node m){
    return n.x*m.y-n.y*m.x;
}
inline double dis(node n,node m){
    return (n.x-m.x)*(n.x-m.x)+(n.y-m.y)*(n.y-m.y);
}
inline bool operator < (node n,node m){
    double t=(n-p[1])*(m-p[1]);
    if(t==0) return dis(n,p[1])<dis(m,p[1]);
    return t<0;
}
void graham(){
    int k=1;
    for(int i=2;i<=n;i++){
        if(p[k].y>p[i].y||p[i].y==p[k].y&&p[k].x>p[i].x){
            k=i;
        }
    }
    swap(p[1],p[k]);
    sort(p+2,p+n+1);
    s[++top]=p[1];s[++top]=p[2];
    for(int i=3;i<=n;i++){
        while(top>1&&(p[i]-s[top-1])*(s[top]-s[top-1])<=0) top--;
        s[++top]=p[i];
    }
}
void solve(){
    n=read();
    for(int i=1;i<=n;i++){
        scanf("%lf%lf",&p[i].x,&p[i].y);
    }
    graham();
    s[top+1]=p[1];
    double ans=0;
    int a,b;
    for(int x=1;x<=top;x++){
        a=x%top+1;b=(x+2)%top+1;
        for(int y=x+2;y<=top;y++){
            while(a%top+1!=y&&(s[y]-s[x])*(s[a+1]-s[x])>(s[y]-s[x])*(s[a]-s[x])) a=a%top+1;
            while(b%top+1!=x&&(s[b+1]-s[x])*(s[y]-s[x])>(s[b]-s[x])*(s[y]-s[x])) b=b%top+1;
            ans=max(ans,(s[y]-s[x])*(s[a]-s[x])+(s[b]-s[x])*(s[y]-s[x]));
        }
    }
    printf("%.3f\n",ans/2);
}
int main(){
    solve();
    return 0;
}

  

 

posted @ 2017-12-06 22:04  zhangenming  阅读(153)  评论(0编辑  收藏  举报