最远城市距离
内存限制: 256 Mb时间限制: 1000 ms
题目描述
大城市的道路是相互平行或垂直的,如果在城市的道路上行走,不能用点与点之间的直线距离计算长度,而是应该定义两个点(设坐标分别为 (x,y) 与 (x′,y′))的城市距离为
∣x−x′∣+∣y−y′∣
给定 n 个点的坐标,请从中寻找两个点,使得它们的城市距离达到最大,并输出这个最大值。
输入格式
第一行:单个整数 n。
第二行到第 n+1 行:每行有两个整数 xi 和 yi,表示一个点的坐标。
输出格式
单个整数:表示最大的城市距离。
数据范围
- 对于 30% 的数据,2≤n≤5,000;
- 对于 60% 的数据,2≤n≤50,000;
- 对于 100% 的数据,2≤n≤500,000。
- −500,000,000≤xi,yi≤500,000,000;
样例数据
输入:
4
0 0
0 1
1 3
3 2
输出:
5
说明:
(0,0)与(3,2)的城市距离是最大的
解析:
我们先来看任意两点的曼哈顿距离公式:
|x−x′|+|y−y′|
嘶,这里面有2个绝对值,有些棘手啊!
绝对值意味着里面的值可正可负。所以,接下来我们要分类讨论。
在下面的式子中,(x,y)为平面上一点,(x′,y′)为平面上另一点。我们可以对原式变形:
- 两个绝对值内都是正数:(x−x′)+(y−y′)=(x+y)−(x′+y′)
- 两个绝对值内都是负数:(−x+x′)+(−y+y′)=(x′+y′)−(x+y)
- 两个绝对值为一正一负:(x−x′)+(−y+y′)=(x−y)−(x′−y′)
- 两个绝对值为一负一正:(−x+x′)+(y−y′)=(x′−y′)−(x−y)
我们把式子这样变形,是为了让减号前的值最大,减号后的值最小。这样我们就只要取一个最大值,一个最小值就可以得出最远距离。而且,每一个点是相互独立的,我们要保证减号两边的运算都只和一个点相关。
我们可以发现,一式和二式等价,三式和四式等价(互为相反数),所以我们只要在每组等价的式子中取正值,再对它们取最大值即可。
而取最大值最小值的工作,只需要边输入边做。
经过观察,我们只需要在输入时取x+y的最大最小值和x−y的最大最小值,因为(x,y)和(x′,y′)在这里是等价的。
详见代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
int maxa, maxs, mina, mins;
cin >> n;
for (int i = 1; i <= n; i++) {
int x, y;
scanf("%d %d", &x, &y);
if (i == 1) {
maxa = mina = x + y;
maxs = mins = x - y;
}
maxa = max(maxa, x + y);
mina = min(mina, x + y);
maxs = max(maxs, x - y);
mins = min(mins, x - y);
}
cout << max(maxa - mina, maxs - mins) << endl;
return 0;
}