题目描述
When the river brought Gerda to the house of the Old Lady who Knew Magic, this lady decided to make Gerda her daughter. She wants Gerda to forget about Kay, so she puts all the roses from the garden underground.
Mole, who lives in this garden, now can watch the roses without going up to the surface. Typical mole is blind, but this mole was granted as special vision by the Old Lady. He can watch any underground objects on any distance, even through the obstacles and other objects. However, the quality of the picture depends on the Manhattan distance to object being observed.
Mole wants to find an optimal point to watch roses, that is such point with integer coordinates that the maximum Manhattan distance to the rose is minimum possible.
As usual, he asks you to help.
Manhattan distance between points (x_{1}, y_{1}, z_{1})(x
1
, y
1
, z
1
) and (x_{2}, y_{2}, z_{2})(x
2
, y
2
, z
2
) is defined as |x_{1}-x_{2}|+|y_{1}-y_{2}|+|z_{1}-z_{2}|∣x
1
−x
2
∣+∣y
1
−y
2
∣+∣z
1
−z
2
∣ .
输入格式
The first line of the input contains an integer tt tt ( 1<=t<=1000001<=t<=100000 ) — the number of test cases. Then follow exactly tt blocks, each containing the description of exactly one test.
The first line of each block contains an integer n_{i}n
i
( 1<=n_{i}<=1000001<=n
i
<=100000 ) — the number of roses in the test. Then follow n_{i}n
i
lines, containing three integers each — the coordinates of the corresponding rose. Note that two or more roses may share the same position.
It’s guaranteed that the sum of all n_{i}n
i
doesn’t exceed 100000100000 and all coordinates are not greater than 10^{18}10
18
by their absolute value.
输出格式
For each of tt test cases print three integers — the coordinates of the optimal point to watch roses. If there are many optimal answers, print any of them.
The coordinates of the optimal point may coincide with the coordinates of any rose.
题意翻译
题目描述
给定一个立体直角坐标系上的nn个整点,求一个整点满足到这nn个整点的曼哈顿距离的最大值最小。
输入格式
第一行一个正整数t(1 \leq t \leq 10^5)t(1≤t≤10
5
)表示数据组数
接下来tt组数据每组数据第一行一个正整数n(1 \leq n , \sum n \leq 10^5)n(1≤n,∑n≤10
5
)表示点数,接下来nn行每行三个整数x_i,y_i,z_i(-10^{18} \leq x_i,y_i,z_i \leq 10^{18})x
i
,y
i
,z
i
(−10
18
≤x
i
,y
i
,z
i
≤10
18
)描述一个整点。
输出格式
对于每组测试数据输出一行三个整数表示选出的整点。
输入输出样例
输入 #1复制
1
5
0 0 4
0 0 -4
0 4 0
4 0 0
1 1 1
输出 #1复制
0 0 0
输入 #2复制
2
1
3 5 9
2
3 5 9
3 5 9
输出 #2复制
3 5 9
3 5 9
说明/提示
In the first sample, the maximum Manhattan distance from the point to the rose is equal to 44 .
In the second sample, the maximum possible distance is 00 . Note that the positions of the roses may coincide with each other and with the position of the optimal point.
显然先二分答案。
考虑如何 check,假设此时二分到的值为 d d d。
则我们可以得到 n n n 个限制 ∣ x − x i ∣ + ∣ y − y i ∣ + ∣ z − z i ∣ ≤ d |x - x_i| + |y - y_i| + |z - z_i| \le d ∣x−xi∣+∣y−yi∣+∣z−zi∣≤d。
不妨设 x i = y i = z i = 0 x_i = y_i = z_i = 0 xi=yi=zi=0,我们考虑 ∣ x ∣ + ∣ y ∣ + ∣ z ∣ ≤ d |x| + |y| + |z| \le d ∣x∣+∣y∣+∣z∣≤d 的情况。
枚举每个绝对值取正取负,我们可以列出 2 3 = 8 2^3 = 8 23=8 个不等式。
合并这 8 n 8n 8n 个不等式,最终会得到一个不等式组:
{ l ≤ x + y + z ≤ r l x ≤ − x + y + z ≤ r x l y ≤ x − y + z ≤ r y l z ≤ x + y − z ≤ r z \begin{cases}l \leq x+y+z \leq r \\lx \leq-x+y+z \leq rx \\ly \leq x-y+z \leq ry \\lz \leq x+y-z \leq rz\end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧l≤x+y+z≤rlx≤−x+y+z≤rxly≤x−y+z≤rylz≤x+y−z≤rz
设 a = − x + y + z a=-x+y+z a=−x+y+z, b = x − y + z b=x-y+z b=x−y+z, c = x + y − z c=x+y-z c=x+y−z,则 x = b + c 2 x=\frac{b+c}{2} x=2b+c, y = a + c 2 y=\frac{a+c}{2} y=2a+c, z = a + b 2 z=\frac{a+b}{2} z=2a+b,且 x + y + z = a + b + c x+y+z = a+b+c x+y+z=a+b+c,且 a , b , c a,b,c a,b,c 奇偶性相同。
令 a = 2 a ′ + r a = 2a^{\prime} + r a=2a′+r, b = 2 b ′ + r b = 2b^{\prime} + r b=2b′+r, c = 2 c ′ + r c = 2c^{\prime} + r c=2c′+r,其中 r ∈ [ 0 , 1 ] r \in [0,1] r∈[0,1],则我们最终得到的不等式组为:
{ l ′ ≤ a ′ + b ′ + c ′ ≤ r ′ l x ′ ≤ a ′ ≤ r x ′ l y ′ ≤ b ′ ≤ r y ′ l z ′ ≤ c ′ ≤ r z ′ \begin{cases}l^{\prime} \leq a^{\prime}+b^{\prime}+c^{\prime} \leq r^{\prime} \\lx^{\prime} \leq a^{\prime} \leq rx^{\prime} \\ly^{\prime} \leq b^{\prime} \leq ry^{\prime} \\lz^{\prime} \leq c^{\prime} \leq rz^{\prime}\end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧l′≤a′+b′+c′≤r′lx′≤a′≤rx′ly′≤b′≤ry′lz′≤c′≤rz′
我们要求出这个不等式组的一组解。
先贪心的设 a ′ = l x ′ a^{\prime} = lx^{\prime} a′=lx′, b ′ = l y ′ b^{\prime} = ly^{\prime} b′=ly′, c ′ = l z ′ c^{\prime} = lz^{\prime} c′=lz′,若不满足 l ′ ≤ a ′ + b ′ + c ′ ≤ r ′ l^{\prime} \leq a^{\prime}+b^{\prime}+c^{\prime} \leq r^{\prime} l′≤a′+b′+c′≤r′,则一个一个调大 a ′ , b ′ , c ′ a^{\prime}, b^{\prime}, c^{\prime} a′,b′,c′。
这样我们就可以 O ( n ) \mathcal O(n) O(n) check 并构造了,时间复杂度 O ( n log w ) \mathcal O(n \log w) O(nlogw)。
#include
#define ll long long
using namespace std;
ll read()
{
ll x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int n;
ll x[100050],y[100050],z[100050],xans,yans,zans;
void Init()
{
for (int i=1;i<=n;i++)
x[i]=y[i]=z[i]=0;
xans=yans=zans=0;
}
bool check(ll mid)
{
ll r1=4e18,r2=4e18,r3=4e18,r4=4e18;
ll l1=-4e18,l2=-4e18,l3=-4e18,l4=-4e18;
for (int i=1;i<=n;i++)
{
r1=min(r1,mid+x[i]+y[i]+z[i]);
r2=min(r2,mid-x[i]+y[i]+z[i]);
r3=min(r3,mid+x[i]-y[i]+z[i]);
r4=min(r4,mid+x[i]+y[i]-z[i]);
l1=max(l1,-mid+x[i]+y[i]+z[i]);
l2=max(l2,-mid-x[i]+y[i]+z[i]);
l3=max(l3,-mid+x[i]-y[i]+z[i]);
l4=max(l4,-mid+x[i]+y[i]-z[i]);
}
for (int i=0;i<=1;i++)
{
ll l11=l1+((l1&1)^i);
ll r11=r1-((r1&1)^i);
ll l21=l2+((l2&1)^i);
ll r21=r2-((r2&1)^i);
ll l31=l3+((l3&1)^i);
ll r31=r3-((r3&1)^i);
ll l41=l4+((l4&1)^i);
ll r41=r4-((r4&1)^i);
if (l11<=r11 && l21<=r21 && l31<=r31 && l41<=r41)
{
ll a=l21;
ll b=l31;
ll c=l41;
if (a+b+c<=r11)
{
if (a+b+c<l11)
{
if (r21<l11-b-c)
a=r21;
else
a=l11-b-c;
}
if (a+b+c<l11)
{
if (r31<l11-a-c)
b=r31;
else
b=l11-a-c;
}
if (a+b+c<l11)
{
if (r41<l11-a-b)
c=r41;
else
c=l11-a-b;
}
if (a+b+c>=l11)
{
xans=(b+c)>>1;
yans=(a+c)>>1;
zans=(a+b)>>1;
return 1;
}
}
}
}
return 0;
}
int main()
{
int T=read();
while (T--)
{
n=read();
Init();
for (int i=1;i<=n;i++)
{
x[i]=read();
y[i]=read();
z[i]=read();
}
if (n==1)
{
cout << x[1] << " " << y[1] << " " << z[1] << endl;
continue;
}
ll left=0,right=4e18;
while (left<=right)
{
ll mid=(left+right)>>1;
if (check(mid))
right=mid-1;
else
left=mid+1;
}
cout << xans << " " << yans << " " << zans << endl;
}
return 0;
}