博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[ BZOJ 3210 ] 花神的浇花集会
阅读量:6881 次
发布时间:2019-06-26

本文共 1482 字,大约阅读时间需要 4 分钟。

\(\\\)


给出\(N​\)个整点的坐标,在坐标系中选择一个整点,使得这个整点到这\(N​\)个点的切比雪夫距离之和最小。

  • \(N\in [1,10^5]\)\(x_i,y_i\in [0,10^5]\)

\(\\\)

\(Solution\)


  • 首先对于一个点,切比雪夫距离并不好快速求出,考虑转化为曼哈顿距离,将每个点\((x_i,y_i)\)变为\((\frac{x_i+y_i}{2},\frac{x_i-y_i}{2})\),关于转化的部分可以参考:。
  • 然后就是经典的运输问题,将两个坐标系的方向分开考虑,考虑一个坐标系上的问题,就是数轴上有一些点,选择一个点到所有点的距离和最小,这个的答案是中位数,可以通过微扰法证明。
  • 于是将横纵坐标拆开排序,分别取中位数,因为选的点只要求是整点,并没有要求是给出点之一,所以直接组合这个点即可。将其还原到切比雪夫问题的坐标系,将得到的点\((x,y)\)变为\((x+y,x-y)\)即可,注意到得到的点的坐标可能不是整点,所以把周围的整点都算一遍取\(min\)就可以了。
  • 关于精度问题, 同样可以采取在中介绍的策略,最后找点的时候再除以\(2\)

\(\\\)

\(Code\)


#include
#include
#include
#include
#include
#include
#include
#define R register#define gc getchar#define N 100010using namespace std;typedef long long ll;ll n,x[N],y[N],sx[N],sy[N],ans=900000000000000000;inline ll rd(){ ll x=0; bool f=0; char c=gc(); while(!isdigit(c)){if(c=='-')f=1;c=gc();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();} return f?-x:x;}inline ll calc(ll nx,ll ny){ ll res=0; for(R ll i=1;i<=n;++i) res+=max(abs(nx-x[i]),abs(ny-y[i])); return res;}int main(){ n=rd(); for(R ll i=1;i<=n;++i){ x[i]=rd(); y[i]=rd(); sx[i]=x[i]+y[i]; sy[i]=x[i]-y[i]; } sort(sx+1,sx+1+n); sort(sy+1,sy+1+n); ll ansx=((sx[(n+1)>>1]+sy[(n+1)>>1])>>1); ll ansy=((sx[(n+1)>>1]-sy[(n+1)>>1])>>1); for(R ll i=-1;i<=1;++i) for(R ll j=-1;j<=1;++j) ans=min(ans,calc(ansx+i,ansy+j)); printf("%lld\n",ans); return 0;}

转载于:https://www.cnblogs.com/SGCollin/p/9638596.html

你可能感兴趣的文章