松鼠搬家 ( 切比雪夫距离 到 曼哈顿距离 )
题意:求切比雪夫距离
直接求不好求,可以转化成曼哈顿距离
切比雪夫:
$$ 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",n); int tin1,tin2; for(int i=1;i<=n;++i) { tin1=read();tin2=read(); //printf("%d %d\n",tin1,tin2); id[i]=i; x[i]=tin1+tin2; y[i]=tin1-tin2; } cout<<get_ans(); }