几何模版-多维最远曼哈顿距离
/* 题意:给定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; }