题目大意:给出平面上的一些点,求这些点中组成的矩形的最大面积。
思路:任意找四个点然后判断肯定是不行的,那么我们不妨来想一想矩形的性质。比如,对角线的交点是两条对角线的中点,对角线相等。这样的话只要找到一对线段,使得他们的中点相同,并且长度相同,那么这两个对角线一定能够组成一个矩形。只有就可以利用叉积求出面积了。
比较坑的一点是,这个题万万不能用double,因为有一个点专门卡double。可以尝试用long double,最好还是避免精度问题,统一用整数。
CODE:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1600
using namespace std;
struct Point{
long long x,y;
Point(long long _ = 0,long long __ = 0):x(_),y(__) {}
bool operator <(const Point &a)const {
if(x == a.x) return y < a.y;
return x < a.x;
}
Point operator -(const Point &a)const {
return Point(x - a.x,y - a.y);
}
bool operator ==(const Point &a)const {
return (x == a.x && y == a.y);
}
void Read() {
scanf("%lld%lld",&x,&y);
}
}point[MAX];
struct Segment{
Point a,b;
Point bi_mid;
long long length;
Segment(Point _,Point __):a(_),b(__) {
Point temp = a - b;
length = temp.x * temp.x + temp.y * temp.y;
bi_mid.x = a.x + b.x;
bi_mid.y = a.y + b.y;
}
Segment() {}
bool operator <(const Segment &a)const {
if(length == a.length) return bi_mid < a.bi_mid;
return length < a.length;
}
}segment[MAX * MAX >> 1];
int points,segments;
inline long long Cross(const Point &a,const Point &b);
inline long long Work(const Segment &a,const Segment &b);
int main()
{
cin >> points;
for(int i = 1;i <= points; ++i)
point[i].Read();
for(int i = 1;i <= points; ++i)
for(int j = i + 1;j <= points; ++j)
segment[++segments] = Segment(point[i],point[j]);
sort(segment + 1,segment + segments + 1);
long long ans = 0;
for(int i = 1;i <= segments; ++i) {
int start = i,end = i;
while(segment[end + 1].length == segment[start].length && segment[end + 1].bi_mid == segment[start].bi_mid)
++end;
for(int j = start;j <= end; ++j)
for(int k = j + 1;k <= end; ++k)
ans = max(ans,Work(segment[j],segment[k]));
i = end;
}
cout << ans << endl;
return 0;
}
inline long long Cross(const Point &a,const Point &b)
{
return a.x * b.y - a.y * b.x;
}
inline long long Work(const Segment &a,const Segment &b)
{
Point p1 = b.a - a.a,p2 = b.b - a.a;
return abs(Cross(p1,p2));
}