洛谷4166 最大土地面积(计算几何)

有毒。。。。

【题目分析】

首先讲一波错误的想法(来自wcr dalao)

为什么要去找最远点对呢?反例太好找了啊!

好的讲讲正解,首先要找最大面积,肯定要在凸包上去找四个点(证明等我思考出来就更传送门)。

然后我们发现:哎呀这个点数怎么才2k啊,哇直接枚举所有对角线不就行了吗?

然后我们再感性理解一下:在对角线两边,三角形的面积呈单峰函数。

所以就可以直接上暴力去找,复杂度O(n^2)。

【代码~】

#include<bits/stdc++.h>
using namespace std;
const int MAXN=2010;

int n,last;
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 pot(const point &a,const point &b){
		return a.x*b.x+a.y*b.y;
	}
	inline double dist(){
		return sqrt(x*x+y*y);
	}
}p[MAXN],q[MAXN];

bool cmp(point a,point b)
{
	int res=(a-p[1])*(b-p[1]);
	if(res!=0)
	  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;
	if(dat!=1)
	  swap(p[1],p[dat]);
	sort(p+2,p+n+1,cmp);
	q[++last]=p[1];
	for(int i=2;i<=n;++i)
	{
		while(last>=3&&(p[i]-q[last-1])*(q[last]-q[last-1])>=0)
		  last--;
		q[++last]=p[i];
	}
}

double calc()
{
	q[0]=q[last];
	double ret=0.0;
	for(int i=0;i<last;++i)
	{
		int p1=i%last,p2=(i+1)%last;        //QAQ这个地方弄了好久啊。。。。。。
		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;
			ret=max(ret,(q[p1]-q[i])*(q[j]-q[i])+(q[j]-q[i])*(q[p2]-q[i]));
		}
	}
	return ret/2;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	  scanf("%lf%lf",&p[i].x,&p[i].y);
	graham();
	double k=calc();
	printf("%.3lf",k);
	return 0;
}

 

posted @ 2018-10-18 11:19  Ishtar~  阅读(174)  评论(0编辑  收藏  举报