1. 程式人生 > >松鼠搬家 ( 切比雪夫距離 到 曼哈頓距離 )

松鼠搬家 ( 切比雪夫距離 到 曼哈頓距離 )

cnblogs 搬家 sort play one read max hid name

題意:求切比雪夫距離

直接求不好求,可以轉化成曼哈頓距離

切比雪夫:

$$ 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(); }
AA

松鼠搬家 ( 切比雪夫距離 到 曼哈頓距離 )