几何模版-多维最远曼哈顿距离

/*
题意:给定N个D维坐标。求最远曼哈顿距离。
解法:对于两个二维坐标A(xi,yi),B(xj,yj).其曼哈顿距离可能为以下四种情况:
(xi-xj)+(yi-yj), (xj-xi)+(yi-yj), (xi-xj)+(yj-yi), (xj-xi)+(yj-yi)
将坐标参数按点来分配之后变形如下:
(xi+yi)-(xj+yj), (-xi+yi)-(-xj+yj), (xi-yi)-(xj-yj), (-xi-yi)-(-xj-yj)
易得每项两个点的参数前的正负符号是一样的。这规律在D维下易证通用。
我们且称如上的(xi+yi)等为点A的“11”状态下的本点有效距离。
由此, 每个坐标参数的正负状态下的最长有效距离减去最短有效距离 即是当前
正负状态下的最远曼哈顿距离。再枚举每个状态,取每个状态的最远曼哈顿距离
的最大值即为答案。
*/


#include <stdio.h>
#define INF 9999999999999.0
#define D 5//空间维数
#define M 100005//坐标个数
struct Point
{
    double x[D];
}pt[M];
double dis[1<<D][M],minx[1<<D],maxx[1<<D];

//去掉绝对值后有2^D种可能
void Get(int N)//取得所有点在指定状态(S)下的“本点有效距离”
{
    int tot=(1<<D);
    for(int s=0;s<tot;s++)//遍历所有维数正负状态
    {
        int coe[D];
        for(int i=0;i<D;i++)//设定当前状态的具体正负参数
        if(s&(1<<i)) coe[i]=-1.0;
        else coe[i]=1.0;

        for(int i=0;i<N;i++)//遍历所有点,确定每个点在当前状态下的“本点有效距离”
        {
            dis[s][i]=0.0;
            for(int j=0;j<D;j++)
            dis[s][i]=dis[s][i]+coe[j]*pt[i].x[j];
        }
    }
}
//取每种可能中的最大差距
void Solve(int N)
{
    int tot=(1<<D);
    double tmp,ans;
    for(int s=0;s<tot;s++)
    {
        minx[s]=INF;
        maxx[s]=-INF;
        for(int i=0;i<N;i++)
        {
            if (minx[s]>dis[s][i]) minx[s]=dis[s][i];
            if (maxx[s]<dis[s][i]) maxx[s]=dis[s][i];
        }
    }
    ans=0.0;
    for(int s=0;s<tot;s++)
    {
        tmp=maxx[s]-minx[s];
        if(tmp>ans) ans=tmp;
    }

    printf("%.2lf\n", ans);
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
        scanf("%lf%lf%lf%lf%lf",&pt[i].x[0],&pt[i].x[1],&pt[i].x[2],&pt[i].x[3],&pt[i].x[4]);
        Get(n);
        Solve(n);
    }
    return 0;
}

 

posted @ 2016-01-25 11:12  蓦辰  阅读(1164)  评论(0编辑  收藏  举报