hdu 4431 绝对值之和最小公式

/*
普通的二分不好写,反正我没写出来,这题核心需要求出绝对值最小公式
sum=|x+10|+|x+5|+|x+1|+|x-2|+|x-6|;sumx[1]=-10;sumx[2]=-15;sumx[3]=-16;sumx[4]=-14;sumx[5]=-8;   
对于第3个点sum=(-1)*3-sumx[3]+sum[5]-sum[3]-(-1)*(5-3);
按照这样就可以直接得到一个点的横纵坐标与其他点的距离和了
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N  110000
#define inf 0x3fffffff
struct node {
int x,y;
}f[N];
int x[N],suma[N];
int y[N],sumb[N];
int cmp(const void *a,const void *b) {
return *(int *)a-*(int *)b;
}
int n;
int seach(int a[N],int u) {
int st=1,en=n,mid;
  while(st<=en) {
    mid=(st+en)/2;
    if(a[mid]==u)return mid;
    if(a[mid]>u)
        en=mid-1;
    else
        st=mid+1;
  }
  return st;
}
int main() {
    int t,i,maxx;
    int xx,yy,sumx,sumy;
    scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        for(i=1;i<=n;i++) {
            scanf("%d%d",&f[i].x,&f[i].y);
            x[i]=f[i].x;
            y[i]=f[i].y;
        }
        suma[0]=0;sumb[0]=0;
        qsort(x+1,n,sizeof(x[0]),cmp);
        qsort(y+1,n,sizeof(y[0]),cmp);
        for(i=1;i<=n;i++) {
            suma[i]=suma[i-1]+x[i];
            sumb[i]=sumb[i-1]+y[i];
        }
        maxx=inf;
        for(i=1;i<=n;i++) {
            xx=seach(x,f[i].x);
            yy=seach(y,f[i].y);
            sumx=xx*x[xx]-suma[xx]+suma[n]-suma[xx]-x[xx]*(n-xx);//
            sumy=yy*y[yy]-sumb[yy]+sumb[n]-sumb[yy]-y[yy]*(n-yy);
            //printf("%d %d\n",sumx,sumy);
            if(maxx>sumx+sumy)
                maxx=sumx+sumy;
        }
        printf("%d\n",maxx);
    }
return 0;}

posted @ 2014-11-01 14:30  HYDhyd  阅读(189)  评论(0编辑  收藏  举报