题解:P1142 轰炸
目前题解区仅有两种做法:
采用基于叉积的极角排序可以兼顾精度和复杂度。具体地,枚举起始点,并算出其余点相对其的向量,对向量进行极角排序,同向的向量会相邻,此时只需要简单统计同向的段的长度即可。
注意事项是同向或反向都是同一直线,因此对于每个起始点,都应当将除自身外所有的点均加入排序(而不应采用
#include <algorithm>
#include <cstdio>
const int maxn = 700;
struct Vector {
int x, y;
Vector(int x = 0, int y = 0) : x(x), y(y){}
friend int cross(const Vector &t1, const Vector &t2) {
return t1.x * t2.y - t1.y * t2.x;
}
friend bool parallel(const Vector &t1, const Vector &t2) {
return !cross(t1, t2);
}
bool operator<(const Vector &t) {
return cross(*this, t) > 0;
}
};
struct Point {
int x, y;
Point(int x = 0, int y = 0) : x(x), y(y){}
Vector operator-(const Point &t) {
return {x - t.x, y - t.y};
}
};
Vector t[maxn + 1];
Point a[maxn + 1];
int ans, now, tot, n;
int main() {
scanf("%d", &n);
ans = 2;
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &a[i].x, &a[i].y);
}
for (int i = 1; i <= n; ++i) {
tot = 0;
for (int j = 1; j <= n; ++j) {
if (i != j) {
t[++tot] = a[i] - a[j];
}
}
std::sort(t + 1, t + tot + 1);
now = 2;
for (int j = 2; j <= tot; ++j) {
if (parallel(t[j], t[j - 1])) {
++now;
}
else {
now = 2;
}
ans = std::max(ans, now);
}
}
printf("%d", ans);
return 0;
}