这个题目思路非常巧妙。
一般思路是枚举两个点求其曼哈顿距离的最大值。但是O(n^2)必超时。
从公式的角度入手, d = |x1 - x2| + |y1 - y2| + |z1 - z2|,去掉绝对值,一共可以得到八种情况(比如说 (x1+y1+z1)-(x2+y2+z2),(-x1+y1+z1)-(-x2+y2+z2)...),把左边看成一个整体,右边一个整体,求两者差的最大值,只需要用最大的减去最小的就行。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define inf -2139062144
#define MOD 20071027
#define MAXN 100005
#define U 1000005
using namespace std;
int x[3][MAXN];
int c[MAXN];
int main()
{
int T,kase=0;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; ++i)
scanf("%d%d%d",&x[0][i],&x[1][i],&x[2][i]);
int ans=inf;
for(int s=0; s<8; ++s)
{
for(int i=1; i<=n; ++i)
{
c[i]=0;
for(int k=0; k<3; ++k)
if(s&(1<<k)) c[i]-=x[k][i];
else c[i]+=x[k][i];
}
int minn=INF,maxn=inf;
for(int i=1; i<=n; ++i)
{
minn=min(minn,c[i]);
maxn=max(maxn,c[i]);
}
ans=max(ans,maxn-minn);
}
printf("Case #%d: %d\n",++kase,ans);
}
return 0;
}