首先解释一下题目里面的两个概念:
-
曼哈顿距离:即 \(|x_a - x_b| + |y_a - y_b|\)
-
欧几里得距离:即 \(\sqrt{(x_a - x_b) ^ 2 + (y_a - y_b)^2}\),也就是两个点在平面上的连线长度。
在图里表示一下就是这样:
在图中,\(AB\) 即为 \(A, B\) 两点间的欧几里得距离,\(AC + BC\) 即为两点间的曼哈顿距离。(图中 \(\angle C = 90 \degree\))
我们可以很容易的看出,两点间的欧几里得距离大于等于他们的曼哈顿距离。因为欧几里得距离就是如图所示三角形的斜边,而曼哈顿距离则为两直角边之和。众所周知,三角形两边之和大于第三边。因此,重要结论如下:
两点间欧氏距离等于曼哈顿距离,当且仅当两点的横坐标或纵坐标相同。
这样就非常简单了。我们搞三个 \(\texttt{map}\),分别记录横坐标相同的点的个数,纵坐标相同的点的个数,横纵坐标都相同的点的个数。从 \(1\) 到 \(n\) 遍历每个点,对于当前点 \((x_i, y_i)\),我们可以选择从之前的横坐标等于 \(x_i\) 的点中任意选一个,方案数为 \(Map_{x_i}\),对于纵坐标同理。但是别忘了减去与当前点重合的点。
于是超级剪短的代码就出来了。
核心代码:
map<int, int> x, y;
map<PII, int> s;
PII p[N]; // PII represents for pair<int, int>
for (int i = 1; i <= n; i ++ ) {
res += x[p[i].x] ++ + y[p[i].y] ++ - s[{p[i].x, p[i].y}] ++ ;
} // 代码压行勿喷
标签:map,Watchmen,曼哈顿,纵坐标,欧几里得,距离,CF650A,两点
From: https://www.cnblogs.com/LcyRegister/p/17001352.html