上海计算机学会2022年5月月赛C++丙组T4最远城市距离

最远城市距离

内存限制: 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′)为平面上另一点。我们可以对原式变形:

  1. 两个绝对值内都是正数:(x−x′)+(y−y′)=(x+y)−(x′+y′)
  2. 两个绝对值内都是负数:(−x+x′)+(−y+y′)=(x′+y′)−(x+y)
  3. 两个绝对值为一正一负:(x−x′)+(−y+y′)=(x−y)−(x′−y′)
  4. 两个绝对值为一负一正:(−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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长春高老师信奥工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值