CF685C. Optimal Point
阿新 • • 發佈:2020-09-11
題目大意
題解
類似二維,二分後變成一個六頂點八面體,維護四對面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\n",xx,yy,zz); } fclose(stdin); fclose(stdout); return 0; }