分析
首先这个距离是切比雪夫距离,得把它转换成曼哈顿距离,也就是把
(
x
,
y
)
(x,y)
(x,y)变成
(
x
+
y
2
,
x
−
y
2
)
(\frac{x+y}{2},\frac{x-y}{2})
(2x+y,2x−y)
为了避免精度,那么选择把坐标扩大一倍,最后答案除以2
然后横坐标和纵坐标显然可以分别处理,那么对于排序后第
i
i
i个坐标
那么
∣
y
1
−
y
i
∣
+
∣
y
2
−
y
i
∣
+
∣
y
n
−
1
−
y
i
∣
+
∣
y
n
−
y
i
∣
|y_1-y_i|+|y_2-y_i|+|y_{n-1}-y_i|+|y_n-y_i|
∣y1−yi∣+∣y2−yi∣+∣yn−1−yi∣+∣yn−yi∣
i
y
i
−
∑
j
=
1
i
y
j
+
∑
j
=
i
+
1
n
y
j
−
(
n
−
i
)
y
i
iy_i-\sum_{j=1}^iy_j+\sum_{j=i+1}^{n}y_j-(n-i)y_i
iyi−j=1∑iyj+j=i+1∑nyj−(n−i)yi
可以用前缀和优化,所以式子可以化为
(
i
+
i
−
n
)
y
i
+
s
n
−
s
i
−
s
i
(i+i-n)y_i+s_n-s_i-s_i
(i+i−n)yi+sn−si−si
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=100011; int x[N],tx[N],n,y[N],ty[N];
typedef unsigned long long ull; ull sx[N],sy[N];
inline signed iut(){
rr int ans=0,f=1; rr char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans*f;
}
signed main(){
n=iut(); rr ull ans=1ll<<63;
for (rr int i=1;i<=n;++i){
rr int xx=iut(),yy=iut();
x[i]=tx[i]=xx+yy,y[i]=ty[i]=xx-yy;
}
sort(tx+1,tx+1+n),sort(ty+1,ty+1+n);
for (rr int i=1;i<=n;++i) sx[i]=sx[i-1]+tx[i];
for (rr int i=1;i<=n;++i) sy[i]=sy[i-1]+ty[i];
for (rr int i=1;i<=n;++i){
rr int px=lower_bound(tx+1,tx+1+n,x[i])-tx; rr ull sum=0;
sum+=1ll*((px<<1)-n)*x[i]+sx[n]-(sx[px]<<1);
rr int py=lower_bound(ty+1,ty+1+n,y[i])-ty;
sum+=1ll*((py<<1)-n)*y[i]+sy[n]-(sy[py]<<1);
ans=ans<sum?ans:sum;
}
return !printf("%llu",ans>>1);
}

本文详细解析了一种将切比雪夫距离转换为曼哈顿距离的算法,通过坐标变换和前缀和优化,有效地解决了在特定场景下计算两点间距离的问题。文章提供了完整的代码实现,包括坐标变换、排序、前缀和计算等关键步骤。
472

被折叠的 条评论
为什么被折叠?



