算法 {切比雪夫距离}

算法 {切比雪夫距离}

切比雪夫距离

定义

二维: 切比雪夫距离(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;
给定若干点 求任意两点的切比距离之和;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值