题目描述
最近某歌手在研究自己的全球巡回演出计划,他将所有心仪的城市都用平面上的一个点来表示,并打算从中挑选出 4 个城市作为这次巡回演出的地点。
为了显示自己与众不同,他要求存在一个矩形使得挑选出的 4 个点恰好是这个矩形的 4 个顶点,并且希望这个矩形的面积最大。
这可急坏了其经纪人,于是他向全球歌迷征集方案,当然你这位歌迷一定不会错过这个机会。
输入格式
从文件input.txt中读入数据,输入文件的第一行是一个正整数NN,表示平面上点的个数(即某歌手心仪的城市数)。接下来的NN行,每行是由空格隔开的两个整数X_iX
i
和Y_iY
i
,表示其对应点的坐标。20%的数据满足N\leq 500N≤500,100%的数据满足N\leq 1500N≤1500,-10^8\leq X_i,Y_i\leq 10^8−10
8
≤X
i
,Y
i
≤10
8
,且输入数据保证答案存在。
输出格式
输出文件 output.txt 仅包含一个非负整数,表示最大的矩形面积。
输入输出样例
输入 #1
8
-2 3
-2 -1
0 3
0 -1
1 -1
2 1
-3 1
-2 1
输出 #1
10
.
.
.
.
.
.
分析
两条线段能作于矩形的对角线有2个条件
1.中点相同
2.长度相同
于是O(n^2)处理出所有直线,排序
找到满足条件的区间,枚举得出答案
.
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
long long ans,cnt;
struct dot
{
long long x,y;
}a[1505];
struct edge
{
long long x,y,l,a,b;
}b[2000005];
bool cmp(edge a,edge b)
{
if (a.x!=b.x) return a.x<b.x; else
if (a.y!=b.y) return a.y<b.y; else return a.l<b.l;
}
long long work(long long x,long long y,long long z)
{
return abs((a[x].x-a[y].x)*(a[y].y-a[z].y)-(a[x].y-a[y].y)*(a[y].x-a[z].x));
}
int main()
{
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%lld%lld",&a[i].x,&a[i].y);
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
{
b[++cnt].x=a[i].x+a[j].x;
b[cnt].y=a[i].y+a[j].y;
b[cnt].l=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
b[cnt].a=i;
b[cnt].b=j;
}
sort(b+1,b+cnt+1,cmp);
for (int i=1,j;i<=cnt;i=j+1)
{
j=i+1;
while (j<=cnt&&b[j].x==b[i].x&&b[j].y==b[i].y&&b[j].l==b[i].l) j++;
j--;
for (int i1=i;i1<=j;i1++)
for (int j1=i1+1;j1<=j;j1++)
ans=max(ans,work(b[i1].a,b[j1].a,b[i1].b));
}
printf("%lld",ans);
return 0;
}