POJ 2926

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

你可能感兴趣的:(poj)