题目大意
题解
类似二维,二分后变成一个六顶点八面体,维护四对面x+y+z,x+y-z,x-y+z,x-y-z的限制
要求对这个不等式组求解,想过一些做法感觉不可行
考虑换元,设A=-x+y=z,B=x-y+z,C=x+y-z,则x+y+z=A+B+C,变成关于A+B+C,A,B,C的限制,这个可以直接搞,就是把ABC都设为下界,之后A+B+C小于下界的话就把ABC增大
还原回去有x=(B+C)/2,y=(A+C)/2,z=(A+B)/2,可能不是整点所以把周围5^3个点都判一遍即可
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define inf 9223372036854775807ll
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define ll long long
//#define file
using namespace std;
ll x[100001],y[100001],z[100001],L,R,Mid,s[2][4],X,Y,Z,x2,y2,z2,xx,yy,zz,ans,S,A,B,C;
int T,n,i,j,k,l;
bool bz;
void swap(ll &x,ll &y) {ll z=x;x=y;y=z;}
bool pd(ll r)
{
ll A,B,C;
fo(i,0,3) s[0][i]=-inf,s[1][i]=inf;
fo(i,1,n)
{
s[0][0]=max(s[0][0],x[i]+y[i]-r+z[i]),s[1][0]=min(s[1][0],x[i]+y[i]+r+z[i]);
s[0][1]=max(s[0][1],x[i]+y[i]-r-z[i]),s[1][1]=min(s[1][1],x[i]+y[i]+r-z[i]);
s[0][2]=max(s[0][2],x[i]-y[i]-r+z[i]),s[1][2]=min(s[1][2],x[i]-y[i]+r+z[i]);
s[0][3]=max(s[0][3],x[i]-y[i]-r-z[i]),s[1][3]=min(s[1][3],x[i]-y[i]+r-z[i]);
}
swap(s[0][3],s[1][3]),s[0][3]=-s[0][3],s[1][3]=-s[1][3];
return (s[0][0]<=s[1][0] && s[0][1]<=s[1][1] && s[0][2]<=s[1][2] && s[0][3]<=s[1][3]) && max(s[0][0],(double)s[0][1]+s[0][2]+s[0][3])<=min(s[1][0],(double)s[1][1]+s[1][2]+s[1][3]);
}
ll add(ll a,ll b)
{
if (a&1) ++a,--b;
a>>=1,b>>=1;
return a+b;
}
ll js(ll X,ll Y,ll Z)
{
ll s,ans=-9223372036854775807ll;
int i;
fo(i,1,n) s=abs(X-x[i])+abs(Y-y[i])+abs(Z-z[i]),ans=max(ans,s);
return ans;
}
int main()
{
#ifdef file
freopen("CF685C.in","r",stdin);
#endif
scanf("%d",&T);
for (;T;--T)
{
scanf("%d",&n);
fo(i,1,n) scanf("%lld%lld%lld",&x[i],&y[i],&z[i]);
L=0;R=6000000000000000000ll;
while (L<R)
{
Mid=add(L,R);
if (!pd(Mid))
L=Mid+1; else R=Mid;
}
pd(L),bz=0;
A=s[0][3],B=s[0][2],C=s[0][1];
if ((double)A+B+C<s[0][0]) A+=min(s[1][3]-s[0][3],s[0][0]-(A+B+C));
if ((double)A+B+C<s[0][0]) B+=min(s[1][2]-s[0][2],s[0][0]-(A+B+C));
if ((double)A+B+C<s[0][0]) C+=min(s[1][1]-s[0][1],s[0][0]-(A+B+C));
X=add(B,C),Y=add(A,C),Z=add(A,B);
xx=X,yy=Y,zz=Z;
ans=js(X,Y,Z);
fo(x2,X-2,X+2)
{
fo(y2,Y-2,Y+2)
{
fo(z2,Z-2,Z+2)
{
S=js(x2,y2,z2);
if (ans>S)
ans=S,xx=x2,yy=y2,zz=z2;
}
}
}
printf("%lld %lld %lld
",xx,yy,zz);
}
fclose(stdin);
fclose(stdout);
return 0;
}