Problem Statement
There are $N$ points on a two-dimensional plane, with the $i$-th point at coordinates $(X_i, Y_i)$. It is guaranteed that no two points are at the same position, and no three points are collinear.
Among the combinations of four points from these points, how many combinations can form a trapezoid as a polygon with those four points as vertices?
Constraints
- $4 \leq N \leq 2,000$
- $0 \leq X_i, Y_i \leq 10^7$ ($1 \leq i \leq N$)
- No two points are at the same location.
- No three points are collinear.
- All input values are integers.
Solving
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
void solve()
{
int n;
cin >> n;
struct Point
{
int x,y;
};
vector<Point> p(n+1);
for(int i=1;i<=n;i++)
{
cin >> p[i].x >> p[i].y;
}
map<pii,int> k;
map<pii,int> mid;
for(int i=1;i<n;i++)
{
for (int j=i+1;j<=n;j++)
{
if(i == j) continue;
int dx = p[i].x - p[j].x;
int dy = p[i].y - p[j].y;
int d = __gcd(abs(dx),abs(dy));
if(d != 0)
{
dx /= d;
dy /= d;
}
// 统一方向变量形式,dx永远是正数
if(dx < 0 or (dx == 0 and dy < 0))
{
dx = -dx;
dy = -dy;
}
k[{dx,dy}]++;
int mx = p[i].x + p[j].x;
int my = p[i].y + p[j].y;
mid[{mx,my}]++; // 记录中点
}
}
int ans = 0;
for (auto x : k)
{
int cnt = x.second;
ans += cnt * (cnt - 1) / 2;
}
int minus = 0;
// 有多少平行四边形要减去一次,因为答案中多算了一次
for (auto x : mid)
{
int cnt = x.second;
minus += cnt * (cnt - 1) / 2;
}
cout << ans - minus << endl;
}
|