松鼠搬家 ( 切比雪夫距离 到 曼哈顿距离 )

题意:求切比雪夫距离

直接求不好求,可以转化成曼哈顿距离

切比雪夫:

$$ d=max( | x_1-x_2 | , | y_1-y_2 | ) $$

曼哈顿距离:

$$ d=| x_1-x_2 | + | y_1-y_2 |$$

$$ d=max( x_1-x_2+y_1-y_2,x_1-x_2+y_2-y_1,x_2-x_1+y_1-y_2,x_2-x_1+y_2-y_1 ) $$

让 $ x_3=x_1+y_1, y_3=x_1-y_1, x_4=x_2+y_2, y_4=x_2-y_2 $

这样 $ x_1=frac{x_3+y_3}{2}, y_1=frac{x_3-y_3}{2} $  ......

此时切比雪夫距离可以表示成

$$ d=frac{|x_3-x_4|-|y_3-y_4|}{2} $$

转化成了类似于曼哈顿距离的东西

只要排个序就行了

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
inline int read()
{
    char q=getchar();int ans=0,flag=1;
    while(q<'0'||q>'9'){if(q=='-')flag=-1;q=getchar();}
    while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
    return ans*flag;
}
const int N=100006;

ll an[N];
int id[N],x[N],y[N];
bool cmp_x(int a,int b)
{
    return x[a]<x[b];
}
bool cmp_y(int a,int b)
{
    return y[a]<y[b];
}

int n;

ll get_ans()
{
    ll tt;
    sort(id+1,id+1+n,cmp_x);
    tt=0;
    for(int i=1;i<=n;++i)
    {
        tt+=x[id[i]];
        an[id[i]]+=((ll)x[id[i]]*i-tt);
    }
    tt=0;
    for(int i=n;i>=1;--i)
    {
        tt+=x[id[i]];
        an[id[i]]+=(tt-(ll)x[id[i]]*(n-i+1));
    }
    sort(id+1,id+1+n,cmp_y);
    tt=0;
    for(int i=1;i<=n;++i)
    {
        tt+=y[id[i]];
        an[id[i]]+=((ll)y[id[i]]*i-tt);
    }
    tt=0;
    for(int i=n;i>=1;--i)
    {
        tt+=y[id[i]];
        an[id[i]]+=(tt-(ll)y[id[i]]*(n-i+1));
    }
    tt=((ll)1<<61);
    for(int i=1;i<=n;++i)
        if(tt>an[i])
            tt=an[i];
    return tt/2.0;
}

int main(){
    
    //freopen("in.in","r",stdin);

    n=read();
    //printf("%d
",n);
    int tin1,tin2;
    for(int i=1;i<=n;++i)
    {
        tin1=read();tin2=read();
        //printf("%d %d
",tin1,tin2);
        id[i]=i;
        x[i]=tin1+tin2;
        y[i]=tin1-tin2;
    }
    cout<<get_ans();
}
AA
原文地址:https://www.cnblogs.com/A-LEAF/p/7669812.html