算法 {切比雪夫距离}
切比雪夫距离
定义
二维: 切比雪夫距离(A,B) = max{ abs(A.x - B.x), abs(A.y - B.y)}
;
三维: 切比雪夫距离(A,B) = max{ abs(A.x - B.x), abs(A.y - B.y), abs(A.z - B.z)}
;
性质
定义一次移动为 往(x+1,y+1), (x-1,y-1), ...
四个斜角移动, 那么如果(x,y)
可以移动到(xx,yy)
, 那么其最小移动次数 就等于他俩之间的切比距离;
@LINK: https://editor.csdn.net/md/?not_checkout=1&articleId=138316298
;
算法
二维切比雪夫距离转换为 曼哈顿距离
定义
切比雪夫距离(A,B) == 曼哈顿距离(A1,B1)
, 其中A1 = ((A.x+A.y)/2, (A.x-A.y)/2); B1 = ((B.x+B.y)/2, (B.x-B.y)/2)
;
证明: 根据曼哈顿空间与切比雪夫空间的等距映射关系, 可以推导出;
性质
算法(如果坐标为整数,则可以化简掉小数)
如果A,B
的坐标 都是整数, 此时: 切比(A, B) = 曼哈顿( A1*2, B1*2) / 2
, 其中A1*2, B1*2
都是整数;
此时显然答案肯定是整数; 然而A1,B1
可能会是小数, 如果用小数存储 会丢精度;
切比(A, B) = 曼哈顿(A1,B1) = abs( (B.x+B.y)/2 - (A.x+A.y)/2) + abs( (B.x-B.y)/2 - (A.x-By)/2) = abs( ? / 2) + abs( ? / 2) = (abs(?) + abs(?)) / 2
, 即我们可以把 把/2
去掉 此时坐标都是整数 然后到最后再加上去;
换句话说, 曼哈顿距离( (x/2,y/2), (xx/2,yy/2) )
, 此时空间放大一倍 那么其曼哈顿距离 也会放大一倍(即(dx,dy) -> (2*dx,2*dy)
因此原来曼哈顿距离为dx+dy
现在是2(dx+dy)
), 因此 原来的曼哈顿距离 等于 曼哈顿距离( (x,y), (xx,yy) ) / 2
;
即: 切比(A, B) = 曼哈顿( A1*2, B1*2) / 2
;
给定若干个点, 求任意两点的切比雪夫距离的最大值
令X: 所有点的x坐标, Y: 所有点的y坐标
, 则{ (X最大值 - X.最小值), (Y最大值 - Y.最小值)}
的最大值 便是答案;
给定若干点 求任意两点的切比距离之和
定义
所有点 转换为 曼哈顿坐标, 就等价于是: 求任意两点的曼哈顿距离之和;
.
扫描各个维度, 然后排序, 用前缀和求解;
代码(坐标为整数)
为避免小数丢精度, 我们这里使用一个技巧(整数坐标下 切比转曼哈顿 可以化简掉小数);
template< class _Point, class _ANS> _ANS ___ChebyShevDistance_GetAllPairsDistances_Integral( std::pair<_Point,_Point> const* _arr, int _length){
_ANS ANS = 0;
std::vector< _ANS> X(_length), Y(_length); // 转化为*曼哈顿坐标*;
for( int i = 0; i < _length; ++i){ X[i] = _arr[i].first+_arr[i].second; Y[i] = _arr[i].first-_arr[i].second;}
{ // 求X维度
std::sort( X.begin(), X.end());
_ANS preSum = 0;
for( int i = 0; i < _length; ++i){
if( i > 0){
ANS += (X[i]*i - preSum);
}
preSum += X[i];
}
}
{ // 求Y维度
std::sort( Y.begin(), Y.end());
_ANS preSum = 0;
for( int i = 0; i < _length; ++i){
if( i > 0){
ANS += (Y[i]*i - preSum);
}
preSum += Y[i];
}
}
ASSERTsystem_( ANS%2 == 0);
ANS /= 2;
return ANS;
} // ___ChebyShevDistance_GetAllPairsDistances_Integral
应用
@LINK: https://editor.csdn.net/md/?not_checkout=1&articleId=138316298
;
给定若干点 求任意两点的切比距离之和;