#凸包#洛谷 4166 [SCOI2007] 最大土地面积

题目

在某块平面土地上有 N 个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大。


分析

将这 n 个点的凸包求出来,如果凸包大小为 2 也就是共线的话面积为 0

如果大小为 3,那么这个四边形最大应该是一个凹四边形,枚举凸包内一点求出面积最大值。

否则这四个点都在凸包上,枚举凸包的对角线,对角线两侧的点利用双指针求出最远点求出面积。


代码

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=2011;
struct Point{
    double x,y;
    Point operator -(const Point &t)const{
    	return (Point){x-t.x,y-t.y};
	}
    bool operator ==(const Point &t)const{
        return x==t.x&&y==t.y;
    }
    bool operator !=(const Point &t)const{
        return x!=t.x||y!=t.y;
    }
}a[N],b[N];
int n,m,o=1; double ans;
double Abs(double x){return x<0?-x:x;}
double Dis(Point x){return x.x*x.x+x.y*x.y;}
double cj(Point x,Point y){return x.x*y.y-x.y*y.x;}
bool cmp(Point x,Point y){
    double t=cj(x-a[1],y-a[1]);
    return t>0||(!t&&Dis(x)<Dis(y));
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    for (int i=1;i<=n;++i) cin>>a[i].x>>a[i].y;
    for (int i=2;i<=n;++i)
        if (a[i].x<a[o].x||(a[i].x==a[o].x&&a[i].y<a[o].y)) o=i;
    swap(a[1],a[o]),sort(a+2,a+1+n,cmp),n=unique(a+1,a+1+n)-a-1;
    b[m=1]=a[1];
    for (int i=2;i<=n;++i){
        while (m>1&&cj(a[i]-b[m-1],b[m]-b[m-1])>=0) --m;
        b[++m]=a[i];
    }
    if (m>3){
        b[m+1]=b[1];
        for (int i=1;i<=m;++i){
            for (int j=(i+1)%m+1,x=i%m+1,y=j%m+1;j!=i;j=j%m+1){
                while ((x%m+1)!=j&&Abs(cj(b[j]-b[i],b[x]-b[i]))<=Abs(cj(b[j]-b[i],b[x+1]-b[i]))) x=x%m+1;
                while ((y%m+1)!=i&&Abs(cj(b[j]-b[i],b[y]-b[i]))<=Abs(cj(b[j]-b[i],b[y+1]-b[i]))) y=y%m+1;
                ans=max(ans,Abs(cj(b[j]-b[i],b[y]-b[i]))+Abs(cj(b[j]-b[i],b[x]-b[i])));
            }
        }
    }else if (m==3){
        ans=1e18;
        for (int i=1;i<=n;++i) if (a[i]!=b[1]&&a[i]!=b[2]&&a[i]!=b[3])
            ans=min(min(ans,Abs(cj(a[i]-b[2],b[3]-b[2]))),min(Abs(cj(a[i]-b[1],b[2]-b[1])),Abs(cj(a[i]-b[1],b[3]-b[1]))));
        ans=Abs(cj(b[2]-b[1],b[3]-b[1]))-ans;
    }
    cout<<fixed<<setprecision(3)<<ans/2;
    return 0;
}
posted @   lemondinosaur  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2020-02-06 2020.02.05【NOIP提高组】模拟A 组
点击右上角即可分享
微信分享提示