首页 > 其他分享 >CF650A Watchmen

CF650A Watchmen

时间:2022-12-23 19:22:59浏览次数:39  
标签:map Watchmen 曼哈顿 纵坐标 欧几里得 距离 CF650A 两点

首先解释一下题目里面的两个概念:

  • 曼哈顿距离:即 \(|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

相关文章