1069: [SCOI2007]最大土地面积

观察数据范围,发现可以接受的复杂度在O(n^2log)

考虑枚举四边形对角线,那么分别找到离对角线两边离他最远的点即可.

先求出所有点构成的凸包,然后用旋转卡壳求出最远点

c++代码如下:

#include<bits/stdc++.h>
#define eps 1e-9
#define rep(i,x,y) for(register int i = x; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x; i >= y; -- i)
using namespace std;
const int N = 2005;
int n,cnt,s[N];
double ans ;
struct Point {
	double x,y;
	Point operator - (const Point b) const { return (Point){x - b.x,y - b.y}; }
	
	double operator * (const Point b) { return x * b.y - y * b.x; }
}p[N];
const bool cmp(Point a,Point b) { return a.x < b.x||a.x == b.x&&a.y < b.y; }
int main()
{
	scanf("%d",&n);
	rep(i,1,n)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	sort(p + 1,p + 1 + n,cmp);
	
	rep(i,1,n)
	{
		while(cnt > 1 && ((p[s[cnt]] - p[s[cnt - 1]])*(p[i] - p[s[cnt]])) < eps) cnt--;
		s[++cnt] = i;
	}
	int lst = cnt;
	repd(i,n - 1,1)
	{
		while(cnt > lst && ((p[s[cnt]] - p[s[cnt - 1]])*(p[i] - p[s[cnt]])) < eps) cnt--;
		s[++cnt] = i;
	}
	
	cnt--;
	
	rep(i,1,cnt)
	{
		int x = i%cnt + 1,y = (i + 2)%cnt + 1;
		rep(j,i + 2,cnt)
		{
			while(x % cnt + 1 != j && fabs((p[s[x]] - p[s[i]]) * (p[s[x]] - p[s[j]])) < fabs((p[s[x + 1]] - p[s[i]]) * (p[s[x + 1]] - p[s[j]])))
				x = x % cnt + 1;
			while(y % cnt + 1 != i && fabs((p[s[y]] - p[s[i]]) * (p[s[y]] - p[s[j]])) < fabs((p[s[y + 1]] - p[s[i]]) * (p[s[y + 1]] - p[s[j]])))
				y = y % cnt + 1;
			ans = max(ans,fabs((p[s[x]] - p[s[i]])*(p[s[x]] - p[s[j]]))+fabs((p[s[y]] - p[s[i]])*(p[s[y]] - p[s[j]])));
		}
	}
	
	printf("%.3lf",ans/2);
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值