最大土地面积-凸包

本文介绍了一种计算平面上四个点构成的最大土地面积的方法,利用凸包算法找到边界点,再通过枚举对角线及其两端点来找出最大面积。代码实现包括点的定义、比较函数、格拉姆扫描算法以及面积计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最大土地面积-凸包

题目描述

题目描述

题解

首先可以发现这四个点必定在凸包上,所以先求出凸包,然后再枚举对角线以及对角线两端到对角线距离最远的点,更新答案即可

代码

#include<bits/stdc++.h>
#define M 2009
using namespace std;
struct point{
	double x,y;
	point(double a=0,double b=0){x=a,y=b;}
	friend inline point operator+(const point &a,const point &b){return point(a.x+b.x,a.y+b.y);}
	friend inline point operator-(const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
	friend inline double operator*(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
	friend inline double operator^(const point &a,const point &b){return a.x*b.x+a.y*b.y;}
	inline double dist(){return sqrt(x*x+y*y);}
}q[M],p[M];
int n,last;
bool cmp(const point &a,const point &b){
	double res=(a-p[1])*(b-p[1]);
	if(res) return res>0;
	return (a-p[1]).dist()<(b-p[1]).dist();
}
void graham(){
	int dat=1;
	for(int i=2;i<=n;i++)
		if(p[i].x<p[dat].x||p[i].x==p[dat].x&&p[i].y<p[dat].y)
			dat=i;
	swap(p[dat],p[1]);
	sort(p+2,p+n+1,cmp);
	q[++last]=p[1];
	for(int i=2;i<=n;i++){
		while(last>2&&(p[i]-q[last-1])*(q[last]-q[last-1])>=0) last--;
		q[++last]=p[i];
	}
}
double calc(){
	double ans=0.0;
	q[0]=q[last];
	for(int i=0;i<last;i++){
		int p1=i%last,p2=(i+1)%last;
		for(int j=i+1;j<last;j++){
			while((q[p1+1]-q[i])*(q[j]-q[i])>(q[p1]-q[i])*(q[j]-q[i])) p1=(p1+1)%last;
			while((q[j]-q[i])*(q[p2+1]-q[i])>(q[j]-q[i])*(q[p2]-q[i])) p2=(p2+1)%last;
			ans=max(ans,(q[p1]-q[i])*(q[j]-q[i])+(q[j]-q[i])*(q[p2]-q[i]));
		}
	}return ans*1.0/2;	
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	graham();
	printf("%.3lf\n",calc());
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值