题意:
三个数组,每个数组中挑出来一个数,求 ( x − y ) 2 + ( x − z ) 2 + ( y − z ) 2 (x-y)^2+(x-z)^2+(y-z)^2 (x−y)2+(x−z)2+(y−z)2 的最小值。
三个数肯定有大有小,先固定最大的数和最小的数,然后枚举中间的数,这个固定的过程可以使用二分来加速,然后枚举过程选择最小值。
AC代码;
const int N = 2e5 + 5;
ll r[N], g[N], b[N];
int nr, ng, nb;
ll cal(ll *a, int na, ll *b, int nb, ll *c, int nc)
{
ll ans = 4e18;
rep(i, 1, na - 1)
{
if (c[1] <= a[i])
{
int pos = lower_bound(b + 1, b + 1 + nb, a[i]) - b;
if (b[pos] == inf)
continue;
int l = 1, r = nc, mid, res;
while (l <= r)
{
mid = (l + r) >> 1;
if (c[mid] <= a[i])
l = mid + 1, res = mid;
else
r = mid - 1;
}
ans = min(ans, (a[i] - c[res]) * (a[i] - c[res]) + (a[i] - b[pos]) * (a[i] - b[pos]) + (c[res] - b[pos]) * (c[res] - b[pos]));
}
}
return ans;
}
int main()
{
int t;
sd(t);
while (t--)
{
sddd(nr, ng, nb);
rep(i, 1, nr)
sd(r[i]);
rep(i, 1, ng)
sd(g[i]);
rep(i, 1, nb)
sd(b[i]);
sort(r + 1, r + 1 + nr);
sort(g + 1, g + 1 + ng);
sort(b + 1, b + 1 + nb);
r[nr + 1] = g[ng + 1] = b[nb + 1] = inf;
ll ans = INF;
ans = min(ans, cal(r, nr + 1, g, ng + 1, b, nb + 1));
ans = min(ans, cal(r, nr + 1, b, nb + 1, g, ng + 1));
ans = min(ans, cal(g, ng + 1, r, nr + 1, b, nb + 1));
ans = min(ans, cal(g, ng + 1, b, nb + 1, r, nr + 1));
ans = min(ans, cal(b, nb + 1, g, ng + 1, r, nr + 1));
ans = min(ans, cal(b, nb + 1, r, nr + 1, g, ng + 1));
pld(ans);
}
return 0;
}