1337D - Xenia and Colorful Gems[二分][枚举]
time limit per test | memory limit per test | input | output |
---|---|---|---|
3 seconds | 256 megabytes | standard input | standard output |
Description:
Xenia is a girl being born a noble. Due to the inflexibility and harshness of her family, Xenia has to find some ways to amuse herself.
Recently Xenia has bought n r n_r nr red gems, n g n_g ng green gems and n b n_b nb blue gems. Each of the gems has a weight.
Now, she is going to pick three gems…
Xenia loves colorful things, so she will pick exactly one gem of each color.
Xenia loves balance, so she will try to pick gems with little difference in weight.
Specifically, supposing the weights of the picked gems are x x x, y y y and z z z, Xenia wants to find the minimum value of ( x − y ) 2 + ( y − z ) 2 + ( z − x ) 2 (x−y)^2+(y−z)^2+(z−x)^2 (x−y)2+(y−z)2+(z−x)2. As her dear friend, can you help her?
Input
The first line contains a single integer t ( 1 ≤ t ≤ 100 ) t (1≤t≤100) t(1≤t≤100) — the number of test cases. Then t t t test cases follow.
The first line of each test case contains three integers n r , n g , n b ( 1 ≤ n r , n g , n b ≤ 1 0 5 ) n_r,n_g,n_b (1≤n_r,n_g,n_b≤10^5) nr,ng,nb(1≤nr,ng,nb≤105) — the number of red gems, green gems and blue gems respectively.
The second line of each test case contains n r n_r nr integers r 1 , r 2 , … , r n r ( 1 ≤ r i ≤ 1 0 9 ) r_1,r_2,…,r_{n_r} (1≤r_i≤10^9) r1,r2,…,rnr(1≤ri≤109) — r_i is the weight of the i i i-th red gem.
The third line of each test case contains n g n_g ng integers g 1 , g 2 , … , g n g ( 1 ≤ g i ≤ 1 0 9 ) g_1,g_2,…,g_{n_g} (1≤g_i≤10^9) g1,g2,…,gng(1≤gi≤109) — g i g_i gi is the weight of the i i i-th green gem.
The fourth line of each test case contains nb integers b 1 , b 2 , … , b n b ( 1 ≤ b i ≤ 1 0 9 ) b_1,b_2,…,b_{n_b} (1≤b_i≤10^9) b1,b2,…,bnb(1≤bi≤109) — b i b_i bi is the weight of the i i i-th blue gem.
It is guaranteed that ∑ n r ≤ 1 0 5 , ∑ n g ≤ 1 0 5 , ∑ n b ≤ 1 0 5 ∑n_r≤10^5, ∑n_g≤10^5, ∑n_b≤10^5 ∑nr≤105,∑ng≤105,∑nb≤105 (the sum for all test cases).
Output
For each test case, print a line contains one integer — the minimum value which Xenia wants to find.
Example input
5
2 2 3
7 8
6 3
3 1 4
1 1 1
1
1
1000000000
2 2 2
1 2
5 4
6 7
2 2 2
1 2
3 4
6 7
3 4 1
3 2 1
7 3 3 4
6
Example output
14
1999999996000000002
24
24
14
Hit
In the first test case, Xenia has the following gems:
If she picks the red gem with weight 7 7 7, the green gem with weight 6 6 6, and the blue gem with weight 4 4 4, she will achieve the most balanced selection with ( x − y ) 2 + ( y − z ) 2 + ( z − x ) 2 = ( 7 − 6 ) 2 + ( 6 − 4 ) 2 + ( 4 − 7 ) 2 = 14 (x−y)^2+(y−z)^2+(z−x)^2=(7−6)^2+(6−4)^2+(4−7)^2=14 (x−y)2+(y−z)2+(z−x)2=(7−6)2+(6−4)2+(4−7)2=14.
分析:
题意:
求
m
i
n
(
(
r
i
−
g
j
)
2
+
(
g
j
−
b
k
)
2
+
(
r
i
−
b
k
)
2
)
min((r_i - g_j)^2 + (g_j- b_k)^2 + (r_i - b_k)^2)
min((ri−gj)2+(gj−bk)2+(ri−bk)2),
其中
1
≤
i
≤
n
r
,
1
≤
j
≤
n
g
,
1
≤
k
≤
n
b
1 \leq i \leq n_r, 1 \leq j \leq n_g, 1 \leq k \leq n_b
1≤i≤nr,1≤j≤ng,1≤k≤nb
做法:
现在看到数字大的题就有种下意识的二分
显然如果我们确定了第一个数,例如确定
r
i
r_i
ri
那么要使得结果最小,剩下的两个数也可以基本确定
找到 第一个大于等于
r
i
r_i
ri 的
g
j
g_j
gj
g
j
g_j
gj 如果固定下来,那么
b
k
b_k
bk 必然是离
r
i
+
g
j
2
\frac{r_i+g_j}{2}
2ri+gj 最近的一个数
r
i
+
g
j
r_i+g_j
ri+gj 是因为
b
k
b_k
bk 的选择对这两边的值都有影响
这里有一个问题,离这个值最近,但是不代表大于等于这个值的数一定是最近的
因此还要求一下跟
b
k
−
1
b_{k-1}
bk−1 的结果,取
m
i
n
min
min
这样看来,求
g
j
g_j
gj 的时候是不是也有这样的可能
其实要取的是前一个才是最近的
这边可以暴力枚举以
r
i
,
g
j
,
b
k
r_i, g_j, b_k
ri,gj,bk 哪一个作为标准来计算
这样就可以遍历到
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 4e5 + 5;
#define min(a, b) ((a)>(b)?(b):(a))
vector<ll> v[3];
int n[3];
ll solve(ll a, ll b, ll c) {
return (a - b) * (a - b) + (a - c) * (a - c) + (b - c) * (b - c);
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
ll x, ans = 4e18;
for(int i = 0; i < 3; ++i) {
scanf("%d", &n[i]); v[i].clear();
}
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < n[i]; ++j) {
scanf("%lld", &x); v[i].push_back(x);
}
}
for(int i = 0; i < 3; ++i)
sort(v[i].begin(), v[i].end());
int t1, t2;
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
for(int k = 0; k < 3; ++k) {
if(i == j || i == k || j == k) continue;
for(auto t : v[i]) {
t1 = lower_bound(v[j].begin(), v[j].end(), t) - v[j].begin();
t1 = min(t1, n[j] - 1);
t2 = lower_bound(v[k].begin(), v[k].end(), (t + v[j][t1] + 1) / 2) - v[k].begin();
t2 = min(t2, n[k] - 1);
ans = min(ans, solve(t, v[j][t1], v[k][t2]));
t2 = max(t2 - 1, 0);
ans = min(ans, solve(t, v[j][t1], v[k][t2]));
// printf("%lld %lld %lld\n", t0, v1[t1], v2[t2]);
// puts("");
}
}
}
}
printf("%lld\n", ans);
}
return 0;
}