暴力枚举
O(N4)
很简单吧,但是会T,可能一分都拿不到
考虑由三个点推出第四个点,我们枚举三个点看它们是不是构成直角且第四个点存在,不考虑数据结构(hash,map)带来的复杂度,是
O(N3)
卡卡常数可以得到20分。
枚举点我们会浪费直角这个条件,不优,根据初中数学,我们知道对角线和中点可以定下一个矩形,那我们就对每两个点存它们的中点和对角线长度(这步骤
O(N2)
),然后hash或者sort,就可以在点的周围找可以构成矩形的点了,总的复杂度
O(N2∗C)
(C为hash常数)或
O(N2∗logN)
,可以过掉100%的数据,我第一次hash常数不够优秀,导致T了,然后换成sort就过了。。。
代码:
/**************************************************************
Problem: 2338
User: waz
Language: C++
Result: Accepted
Time:1840 ms
Memory:72092 kb
****************************************************************/
#include <cstdio>
#include <algorithm>
const int MaxN = 1510;
struct Point {
int X, Y;
Point operator + (Point That) {
return (Point) { X + That.X, Y + That.Y };
}
Point operator - (Point That) {
return (Point) { X - That.X, Y - That.Y };
}
bool operator == (Point That) const {
return X == That.X && Y == That.Y;
}
bool operator < (Point That) const {
return X < That.X || (X == That.X && Y < That.Y);
}
} P[MaxN];
struct Line {
Point A, B;
Point Mid;
long long Dist;
bool operator == (Line That) const {
return Mid == That.Mid && Dist == That.Dist;
}
bool operator < (Line That) const {
return Mid < That.Mid || (Mid == That.Mid && Dist < That.Dist);
}
} L[MaxN * MaxN];
int Cnt, N;
long long Dist(Point A, Point B) {
return (long long)(A.X - B.X) * (A.X - B.X) + (long long)(A.Y - B.Y) * (A.Y - B.Y);
}
void Link(Point A, Point B) {
L[++Cnt] = (Line) {A, B, A + B, Dist(A, B)};
}
long long Cross(Point A, Point B) {
return (long long)A.X * B.Y - (long long)B.X * A.Y;
}
long long Abs(long long X) {
return X < 0 ? -X : X;
}
long long Ans;
int main() {
scanf("%d", &N);
for (int i = 1; i <= N; i++)
scanf("%d%d", &P[i].X, &P[i].Y);
/*Link((Point){1, 1}, (Point){3, 3});
Link((Point){1, 3}, (Point){3, 1});
printf("%d\n", L[1] < L[2]);*/
for (int i = 1; i <= N; i++)
for (int j = i + 1; j <= N; j++)
Link(P[i], P[j]);
std :: sort(L + 1, L + Cnt + 1);
/*puts("\n\n\n");
for (int i = 1; i <= Cnt; i++)
printf("%d %d %I64d\n", L[i].Mid.X, L[i].Mid.Y, L[i].Dist);*/
Line *First = L + 1;
for (int i = 2; i <= Cnt; i++) {
Line *Ln = L + i;
if (*First == *Ln) {
long long Area;
for (Line *I = First; I < Ln; I++) {
Area = Abs(Cross(Ln -> A - I -> A, Ln -> B - I -> A));
if (Ans < Area) Ans = Area;
}
//printf("%I64d\n", Area);
}
else First = Ln;
}
printf("%lld\n", Ans);
return 0;
}