洛谷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;
}