题意:求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 }