题目链接:https://vjudge.net/problem/CodeForces-1337D
题目大意:从三个数组中分别取出x,y,z;
使(x−y)2+(y−z)2+(z−x)2 最小
思路:先固定一个数,然后找与它最近的两个数
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
int rr[maxn];
int gg[maxn];
int bb[maxn];
ll ans;
ll sum(int x,int y,int z)
{
return 1LL*(x-y)*(x-y)+1LL*(z-x)*(z-x)+1LL*(y-z)*(y-z); ///1ll不能丢
}
void solve(int a[],int b[],int c[],int x,int y,int z)
{
for(int i=1; i<=y; i++)
{
int t1=lower_bound(a+1,a+1+x,b[i])-a; ///lower_bound()返回值是一个迭代器,返回指向大于等于key的第一个值的位置
int t2=lower_bound(c+1,c+1+z,b[i])-c;
if(t1>x||t1<=x&&a[t1]>b[i]) ///注意***a<b<c
t1--; ///*****易忽略
if(t1>=1&&t1<=x&&t2>=1&&t2<=z)
{
ll res=sum(a[t1],b[i],c[t2]);
ans=min(ans,res);
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int r,g,b;
scanf("%d%d%d",&r,&g,&b);
for(int i=1; i<=r; i++)
{
scanf("%d",&rr[i]);
}
for(int i=1; i<=g; i++)
{
scanf("%d",&gg[i]);
}
for(int i=1; i<=b; i++)
{
scanf("%d",&bb[i]);
}
sort(rr+1,rr+1+r);
sort(gg+1,gg+1+g);
sort(bb+1,bb+1+b);
ans=9223372036854775807; ///long long的最大取值
solve(rr,gg,bb,r,g,b); ///x,y,z的大小顺序有6种,枚举每一种后取最小值
solve(rr,bb,gg,r,b,g);
solve(gg,bb,rr,g,b,r);
solve(bb,rr,gg,b,r,g);
solve(gg,rr,bb,g,r,b);
solve(bb,gg,rr,b,g,r);
printf("%lld\n",ans);
}
}