HDU 4312 Contest 2

题目要求两点间的最大值作为距离即:

 

即是切比雪夫距离。而切比雪夫距离与曼哈顿距离的转换却很巧妙。

把平面坐标所有点绕原点逆向旋转45度后,所得点的曼哈顿距离之和除以√2,即是切雪比夫距离。旋转点的公式是

 

提取无理数,即每个新坐标可以是(x-y,x+y)。计算其曼哈顿距离后除以2即可。

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define LL __int64
using namespace std;

struct point{
    int x,y;
    int num;
}acm[100005];
int n;

bool cmpx(point a, point b){
    if(a.x<b.x) return true;
    return false;
}
bool cmpy(point a,point b){
    if(a.y<b.y) return true;
    return false;
}

LL distx[100005],disty[100005];

LL mint(LL a,LL b){
    if(a<b) return a;
    return b;
}

void init(){
    for(int i=0;i<n;i++)
    distx[i]=disty[i]=0;
}

int main(){
    int T,a,b;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        init();
        for(int i=0;i<n;i++){
            scanf("%d%d",&a,&b);
            acm[i].x=a-b; acm[i].y=a+b;
            acm[i].num=i;
        }
        LL tmp;
        sort(acm,acm+n,cmpx);
        tmp=0;
        for(int i=0;i<n;i++){
            if(!i)
                tmp=distx[acm[i].num]=0;
            else{
                distx[acm[i].num]=tmp=tmp+(LL)i*((LL)acm[i].x-(LL)acm[i-1].x);
            }
        }
        tmp=0;
        for(int i=n-1;i>=0;i--){
            if(i==n-1){
                tmp=0;
                distx[acm[i].num]+=tmp;
            }
            else {
                tmp=tmp+(LL)(n-1-i)*((LL)acm[i+1].x-(LL)acm[i].x);
                distx[acm[i].num]+=tmp;
            }
        }
        sort(acm,acm+n,cmpy);
        for(int i=0;i<n;i++){
            if(!i)
            disty[acm[i].num]=tmp=0;
            else{
                disty[acm[i].num]=tmp=tmp+(LL)i*((LL)acm[i].y-(LL)acm[i-1].y);
            }
        }
        for(int i=n-1;i>=0;i--){
            if(i==n-1){
                tmp=0;
                disty[acm[i].num]+=tmp;
            }
            else {
                tmp=tmp+(LL)(n-1-i)*((LL)acm[i+1].y-(LL)acm[i].y);
                disty[acm[i].num]+=tmp;
            }
        }
        LL ans=distx[0]+disty[0];
        for(int i=1;i<n;i++)
        ans=mint(ans,distx[i]+disty[i]);
        printf("%I64d\n",ans/2);
    }
    return 0;
}

 

  

 

posted @ 2014-10-29 16:22  chenjunjie1994  阅读(217)  评论(0编辑  收藏  举报