HDU Meeting point-1 曼哈顿距离

链接戳

暴力吧……大概?

为了减轻暴力的负担,稍微处理一下,并不复杂

对于某两点间的曼哈顿距离,dis=abs(x1-x2)+abs(y1-y2)

这里点很多很多,很容易想到,为了简化处理,可以利用前缀和,然后我们就需要想办法处理一下绝对值的问题

如果我们对两点间的大小进行排序,就可以把绝对值去掉啦

对横纵坐标分别排序,分别求 sumx[i]=i*x[i]-pre_sumx[i-1]+pre_sumx[n]-prex_sumx[i]-(n-i)*x[i];

                                                sumy[i]=i*y[i]-pre_sumy[i-1]+pre_sumy[n]-pre_sumy[i]-(n-i)*y[i];

然后暴力扫一遍,记录i为中心时的最小sumx[i]+sumy[i]

虽然为了处理横纵坐标前缀和的问题是分开考虑,但是最后结果的处理不是,所以用结构体保存一下横纵坐标和sumx(sumy)就可以了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX= 1e5+5;
ll t,n,presumx[MAX],presumy[MAX];
struct pos
{
    ll x,y,mark;
}p[MAX];
bool cmpx(pos a,pos b)
{
    if(a.x==b.x)
      return a.y<b.y;
    return a.x<b.x;
}
bool cmpy(pos a,pos b)
{
    if(a.y==b.y)
      return a.x<b.x;
    return a.y<b.y;
}
int main()
{
  cin>>t;
  while(t--)
  {
      cin>>n;
      ll ans=1e18;
      presumx[0]=0,presumy[0]=0;
      for(int i=1;i<=n;i++)
      cin>>p[i].x>>p[i].y;
      sort(p+1,p+n+1,cmpx);
      for(int i=1;i<=n;i++)
       presumx[i]=presumx[i-1]+p[i].x;
      for(int i=1;i<=n;i++)
      {
       ll tempx=p[i].x*(i-1)-presumx[i-1]+presumx[n]-presumx[i]-p[i].x*(n-i);
       p[i].mark=tempx;
      }
      sort(p+1,p+1+n,cmpy);
      for(int i=1;i<=n;i++)
       presumy[i]=presumy[i-1]+p[i].y;    
      for(int i=1;i<=n;i++)
      {
       ll tempy=p[i].y*(i-1)-presumy[i-1]+presumy[n]-presumy[i]-p[i].y*(n-i);
      ans=min(ans,p[i].mark+tempy);    
      }
    cout<<ans<<endl;
 }
 return 0;       
} 

 

posted @ 2018-01-04 21:28  #Egoist#  阅读(179)  评论(0编辑  收藏  举报