题意:给出n个5维坐标点,求最远两点的曼哈顿距离。
分析:对于两维的情况,两个点(x1,y1)(x2,y2)之间的距离为|x1-x2|+|y1-y2|,可能取±(x1-x2)±(y1-y2),假如真实的情况是(x1-x2)+(y1-y2),那个在其他情况下算出来的关于这两个点的最大距离肯定比这个小(去掉绝对值符号了),这个式子除了对应同一维的两个值(如:x1和x2)是相减关系外(但不一定谁减谁)其余符号都是不确定的。我们可以把这个相减关系提取出来,变为(±x1±y1)-(±x2±y2)。(注意:这里x1和x2前面的符号是一致的,y1和y2前面的符号是一致的,这样才能保证对应值仍保持相减关系)。这样一来我们就可以看作每个点有一个权值±x±y。只要枚举每一维的分量前面的符号即可,对于每一次枚举算出所有的n个点中权值最大的和最小的,求差,更新答案求最大即可。
View Code
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
#define maxn 100005
int n;
double f[maxn][6];
void input()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
for (int j = 0; j < 5; j++)
scanf("%lf", &f[i][j]);
}
void work()
{
double a, b;
double ans = 0;
for (int k = 0; k < (1 << 5); k++)
{
a = -0x3f3f3f3f;
b = 0x3f3f3f3f;
for (int i = 0; i < n; i++)
{
double temp = 0;
for (int j = 0; j < 5; j++)
temp += f[i][j] * (((k >> j) & 1) * 2 - 1);
a = max(a, temp);
b = min(b, temp);
}
ans = max(ans, a - b);
}
printf("%.2f\n", ans);
}
int main()
{
//freopen("t.txt", "r", stdin);
input();
work();
return 0;
}