题意:求n个五维向量的曼哈顿距离。
题解:设点i的坐标为(Xi,Yi,Zi,Wi,Ti),那么它与j的曼哈顿距离为|Xi-Xj|+|Yi-Yj|+|Zi-Zj|+|Wi-Wj|+|Ti-Tj|,去掉绝对值后,可能要取反或者不取,可以看出,若把所有情况全部考虑,答案结果有2^5种,但是由于本来是有绝对值的,可能某个本来是正数的值取了反,某个负数有没有取,但这样肯定只能使原数变小,所以我们要的结果实际上是2^5中最大的那个。
去掉绝对值后,原始变为?(Xi-Xj)+?(Yi-Yj)+?(Zi-Zj)+?(Wi-Wj)+?(Ti-Tj),问号即为需要枚举的那个,但如果这样直接去算,会是2^5*n^2的,实际上,可以将i,j分开,变成(?Xi+?Yi+?Zi+?Wi+?Ti)-(?Xj+?Yj+?Zj+?Wj+?Tj),并且可以知道,对应的?的正负情况都是一样的,即Xi与Xj的?一样,那么只需要算出每一个点的2^5种情况,然后同类相减再取最大即可。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 double po[100005][5]; 6 int main() 7 { 8 int n; 9 while(scanf("%d",&n)!=EOF) 10 { 11 for(int i=0;i<n;i++) 12 scanf("%lf%lf%lf%lf%lf",&po[i][0],&po[i][1],&po[i][2],&po[i][3],&po[i][4]); 13 double ans=0,mmin,mmax; 14 int len=1<<5; 15 for(int i=0;i<len;i++) 16 { 17 mmin=1e50,mmax=-mmin; 18 for(int j=0;j<n;j++) 19 { 20 double t=0; 21 for(int k=0;k<5;k++) 22 { 23 if((1<<k)&i) 24 t+=po[j][k]; 25 else 26 t-=po[j][k]; 27 } 28 mmin=min(mmin,t); 29 mmax=max(mmax,t); 30 } 31 ans=max(mmax-mmin,ans); 32 } 33 printf("%.2f\n",ans); 34 } 35 return 0; 36 }