IAI 2022年5月丙组 T4 题解

题意

n n n 个点,每个点坐标为 ( x i , y i ) (x_i, y_i) (xi,yi)
要求我们其中找到两个点,使得这两个点之间的曼哈顿距离最大。

暴力求解

首先,我们想到一个暴力的算法。

LL maxx=0;
for (LL i=1; i<=n; i++) {
	for (LL j=1; j<=n; j++) {
		if (i==j) {
			//同一个点
			continue;
		}
		maxx = max(maxx, abs(x[i]-x[j])+abs(y[i]-y[j]);
	}
}

时间复杂度

很容易知道暴力的时间复杂度为 O ( N 2 ) O(N^2) O(N2)
由于本题的 n n n 相对比较大,达到 1 0 5 10^5 105 级别,因此这样的算法本题一定是 TLE。

优化算法

根据暴力的算法,我们知道需要优化部分就是 ∣ x i − x j ∣ + ∣ y i − y j ∣ |x_i-x_j|+|y_i-y_j| xixj+yiyj
为了不失通用性,我们可以假设这两点就是 x 1 x_1 x1 x 2 x_2 x2。那么本题就变为求 ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ |x_1-x_2|+|y_1-y_2| x1x2+y1y2
我们分类讨论:

  1. x 1 > x 2 , y 1 > y 2 x_1>x_2, y_1> y_2 x1>x2,y1>y2,变为 x 1 − x 2 + y 1 − y 2 → ( x 1 + y 1 ) + ( ( − x 2 ) + ( − y 2 ) ) x_1-x_2+y_1-y_2 \to (x_1+y_1)+((-x_2)+(-y_2)) x1x2+y1y2(x1+y1)+((x2)+(y2))
  2. x 1 > x 2 , y 1 < y 2 x_1>x_2, y_1<y_2 x1>x2,y1<y2,变为 x 1 − x 2 + y 2 − y 1 → ( x 1 − y 1 ) + ( ( − x 2 ) + y 2 ) x_1-x_2+y_2-y_1 \to (x_1-y_1)+((-x_2)+y_2) x1x2+y2y1(x1y1)+((x2)+y2)
  3. x 1 < x 2 , y 1 > y 2 x_1<x_2, y_1>y_2 x1<x2,y1>y2,变为 x 2 − x 1 + y 1 − y 2 → ( − ( x 1 ) + y 1 ) + ( x 2 − y 2 ) x_2-x_1+y_1-y_2 \to (-(x_1)+y_1)+(x_2-y_2) x2x1+y1y2((x1)+y1)+(x2y2)
  4. x 1 < x 2 , y 1 < y 2 x_1<x_2, y_1<y_2 x1<x2,y1<y2,变为 x 2 − x 1 + y 2 − y 1 → ( ( − x 1 ) + ( − y 1 ) ) + ( x 2 + y 2 ) x_2-x_1+y_2-y_1 \to ((-x_1)+(-y_1))+(x_2+y_2) x2x1+y2y1((x1)+(y1))+(x2+y2)

通过观察上面的结果,我们发现,需要计算如下 4 4 4 个部分: x 1 + y 1 , x 1 − y 1 , − x 1 + y 1 , − x 1 − y 1 x_1+y_1, x_1-y_1, -x_1+y_1, -x_1-y_1 x1+y1,x1y1,x1+y1,x1y1 即可。
也就是说,每次将一个点,分解为 4 4 4 个点。通过分别对 4 4 4 个方向点排序,这样最小值在下标为 1 1 1 的数组,最大值在下标为 n n n 的数组中。我们只需要计算一下这 4 4 4 个方向点的最大值即为答案。

AC 参考

#include <bits/stdc++.h>
using namespace std;
using LL=long long;
const int N=1e6+10;
LL a[6][N];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	LL n;
	cin>>n;
	for (LL i=1; i<=n; i++) {
		LL x,y;
		cin>>x>>y;
		a[1][i]=x+y;
		a[2][i]=-x+y;
		a[3][i]=x-y;
		a[4][i]=-x-y;
	}
	for (LL i=1; i<=4; i++) {
		sort(a[i]+1, a[i]+1+n);
	}

	LL maxx=0;
	for (LL i=1; i<=4; i++) {
		maxx=max(maxx, a[i][n]-a[i][1]);
	}
	cout<<maxx<<"\n";

	return 0;
}

时间复杂度

O ( n l o g n ) O(nlogn) O(nlogn),也就是排序占用了最多的时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力的老周

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

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

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

打赏作者

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

抵扣说明:

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

余额充值