题解 P5098 【[USACO2004OPEN]Cave Cows 3 洞穴里的牛之三】

Heartlessly

2019-06-19 07:50:17

Solution

## Description 给定 $n$ 个点,每个点的坐标为 $(x,y)$,求曼哈顿距离的最大点对,输出这个最大值。 $(1 \leq n \leq 5 \times 10^4,-10^6 \leq x,y \leq 10^6)$ ## Solution 1 根据题意,对于式子 $\left | x_1-x_2\right| +\left | y_1-y_2\right| $,我们可以分成四种情况考虑: 第一种情况:$x_1 - x_2 \geq 0,y_1 - y_2 \geq 0$ ![VDSc36.png](https://s2.ax1x.com/2019/06/08/VDSc36.png) 第二种情况:$x_1 - x_2 < 0,y_1 - y_2 \geq 0$ ![VDSWuD.png](https://s2.ax1x.com/2019/06/08/VDSWuD.png) 第三种情况:$x_1 - x_2 \geq 0,y_1 - y_2 < 0$ ![VDS2jO.png](https://s2.ax1x.com/2019/06/08/VDS2jO.png) 第四种情况:$x_1 - x_2 < 0,y_1 - y_2 < 0$ ![VDSfDe.png](https://s2.ax1x.com/2019/06/08/VDSfDe.png) 每种情况的答案要么只与 $x+y$ 的值有关,要么只与 $x-y$ 的值有关,所以最后的答案为 $$ \max \begin{Bmatrix} \max \begin{Bmatrix} x_i + y_i \end{Bmatrix} - \min \begin{Bmatrix} x_i + y_i \end{Bmatrix},\max \begin{Bmatrix} x_i - y_i \end{Bmatrix} - \min \begin{Bmatrix} x_i - y_i \end{Bmatrix} \end{Bmatrix} $$ ## Code 1 ```cpp #include <bits/stdc++.h> using namespace std; template <class T> inline void read(T &x) { x = 0; char c = getchar(); bool f = 0; for (; !isdigit(c); c = getchar()) f ^= c == '-'; for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48); x = f ? -x : x; } template <class T> inline void write(T x) { if (x < 0) { putchar('-'); x = -x; } T y = 1; int len = 1; for (; y <= x / 10; y *= 10) ++len; for (; len; --len, x %= y, y /= 10) putchar(x / y + 48); } int n, x, y, minx = 0x7fffffff, maxx, miny = 0x7fffffff, maxy; int main() { read(n); for (int i = 1; i <= n; i++) { read(x), read(y); minx = min(minx, x + y), maxx = max(maxx, x + y); miny = min(miny, x - y), maxy = max(maxy, x - y); } write(max(maxx - minx, maxy - miny)); putchar('\n'); return 0; } ``` ## Solution 2 我们考虑将题目所求的 **曼哈顿距离** 转化为 **切比雪夫距离**,即把每个点的坐标 $(x,y)$ 变为 $(x + y, x - y)$ 。 所求的答案就变为 $\max \begin{Bmatrix} \max\begin{Bmatrix} \left | x_i - x_j\right| ,\left | y_i - y_j\right| \end{Bmatrix} \end{Bmatrix}$ 。 在所有点中,横坐标之差的最大值和纵坐标之差的最大值都有可能成为答案,所以我们只需要预处理出 $x,y$ 的最大值和最小值即可。时间复杂度为 $O(n)$ 。 ## Code 2 ```cpp #include <bits/stdc++.h> using namespace std; template <class T> inline void read(T &x) { x = 0; char c = getchar(); bool f = 0; for (; !isdigit(c); c = getchar()) f ^= c == '-'; for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48); x = f ? -x : x; } template <class T> inline void write(T x) { if (x < 0) { putchar('-'); x = -x; } T y = 1; int len = 1; for (; y <= x / 10; y *= 10) ++len; for (; len; --len, x %= y, y /= 10) putchar(x / y + 48); } int n, x, y, a, b, minx = 0x7fffffff, maxx, miny = 0x7fffffff, maxy; int main() { read(n); for (int i = 1; i <= n; i++) { read(a), read(b); x = a + b, y = a - b; minx = min(minx, x), maxx = max(maxx, x); miny = min(miny, y), maxy = max(maxy, y); } write(max(maxx - minx, maxy - miny)); putchar('\n'); return 0; } ```