题目描述
题目大意:给出二维平面上的n个点,求一个最大的矩形,它的顶点都在给出的点上。
题解
首先预处理出所有的线段,中点相同、长度相同的两条线段可以组成一个合法的矩形
将所有的线段按照一维中点、一维长度、一维斜率排序,对于中点相同、长度相同的线段必定在一段区间里,并且对于一条线段,取到最大值的另一条线段单峰,用两个指针扫一下就行了
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define db double
#define LL long long
#define N 1505
const LL inf=1e18;
int n,cnt;
LL ans,x[N],y[N];
struct Seg
{
int id,jd;
LL x,y,len;
double k;
}s[N*N];
LL qr(LL x){return x*x;}
int cmp(Seg a,Seg b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y)||(a.x==b.x&&a.y==b.y&&a.len<b.len)||(a.x==b.x&&a.y==b.y&&a.len==b.len&&a.k<b.k);
}
LL Abs(LL x){return (x>0)?x:-x;}
LL Area(Seg a,Seg b)
{
LL vx=x[b.id]-x[a.id],vy=y[b.id]-y[a.id];
LL wx=x[b.jd]-x[a.id],wy=y[b.jd]-y[a.id];
return Abs(vx*wy-vy*wx);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%lld%lld",&x[i],&y[i]);
for (int i=1;i<=n;++i)
for (int j=i+1;j<=n;++j)
{
++cnt;
s[cnt].id=i,s[cnt].jd=j;
s[cnt].x=x[i]+x[j],s[cnt].y=y[i]+y[j];
s[cnt].len=qr(x[i]-x[j])+qr(y[i]-y[j]);
if (x[i]==x[j]) s[cnt].k=inf;
else s[cnt].k=((db)y[i]-(db)y[j])/((db)x[i]-(db)x[j]);
}
sort(s+1,s+cnt+1,cmp);
for (int i=1,j;i<=cnt;i=j+1)
{
j=i;
while (s[j].x==s[i].x&&s[j].y==s[i].y&&s[j].len==s[i].len)
++j;
--j;
int l=i,r=i;
while (l<=j)
{
r=max(r,l);
while (r<j&&Area(s[l],s[r])<=Area(s[l],s[r+1]))
++r;
ans=max(ans,Area(s[l],s[r]));
++l;
}
}
printf("%lld\n",ans);
}