D. Xenia and Colorful Gems
题目大意:给你三个数组a , b , c ,在这三个数组中找每个数组找一个数,这三个数为x,y,z, 令ans=(x-y)^2+(y-z)^2+(z-x)^2,求ans的最
小值为多少。
解题思路:
第一种:最小值一定是三个值最接近的时候,则此时可以考虑在给三个数组进行排序后,用 i , j , k 三个指针进行进行贪心,是最终的最小值一步步逼近即可。
第二种:对数组a进行遍历,通过二分查找b数组最逼近a的值,设a数组中的数为x,b数组中的数为y,在对c数组进行二分查找最逼近(x+y)/2 的数,这样才能使当a数组中的数为x时,值最小。
代码:
方法一:
#include<bits/stdc++.h>
#define ll long long
#define MOD 998244353
#define INF 0x3f3f3f3f3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
inline ll solve(ll w,ll e,ll r)
{
return (ll)(w-e)*(w-e)+(ll)(e-r)*(e-r)+(ll)(w-r)*(w-r);
}
ll v1[100005];
ll v2[100005];
ll v3[100005];
int main()
{
ll t,a,b,c;
cin>>t;
while(t--){
cin>>a>>b>>c;
for(int i=0;i<a;i++){
scanf("%lld",&v1[i]);
}
for(int i=0;i<b;i++){
scanf("%lld",&v2[i]);
}
for(int i=0;i<c;i++){
scanf("%lld",&v3[i]);
}
sort(v1,v1+a);
sort(v2,v2+b);
sort(v3,v3+c);
ll minn=INF;
ll pos2,pos3;
ll pos22;
for(int i=0;i<a;i++){
pos2=lower_bound(v2,v2+b,v1[i])-v2;
if(pos2<b){
pos3=lower_bound(v3,v3+c,(v1[i]+v2[pos2])>>1)-v3;
if(pos3<c){
minn=min(minn,solve(v1[i],v2[pos2],v3[pos3]));
pos22=lower_bound(v2,v2+b,(v1[i]+v3[pos3])>>1)-v2;
if(pos22<b){
minn=min(minn,solve(v1[i],v2[pos22],v3[pos3]));
}
if(pos22>0){
minn=min(minn,solve(v1[i],v2[pos22-1],v3[pos3]));
}
}
if(pos3>0){
minn=min(minn,solve(v1[i],v2[pos2],v3[pos3-1]));
pos22=lower_bound(v2,v2+b,(v1[i]+v3[pos3-1])>>1)-v2;
if(pos22<b){
minn=min(minn,solve(v1[i],v2[pos22],v3[pos3-1]));
}
if(pos22>0){
minn=min(minn,solve(v1[i],v2[pos22-1],v3[pos3-1]));
}
}
}
if(pos2>0){
pos3=lower_bound(v3,v3+c,(v1[i]+v2[pos2-1])>>1)-v3;
if(pos3<c){
minn=min(minn,solve(v1[i],v2[pos2-1],v3[pos3]));
pos22=lower_bound(v2,v2+b,(v1[i]+v3[pos3])>>1)-v2;
if(pos2<b){
minn=min(minn,solve(v1[i],v2[pos22],v3[pos3]));
}
if(pos22>0){
minn=min(minn,solve(v1[i],v2[pos22-1],v3[pos3]));
}
}
if(pos3>0){
minn=min(minn,solve(v1[i],v2[pos2-1],v3[pos3-1]));
pos22=lower_bound(v2,v2+b,(v1[i]+v3[pos3-1])>>1)-v2;
if(pos22<b){
minn=min(minn,solve(v1[i],v2[pos22],v3[pos3-1]));
}
if(pos22>0){
minn=min(minn,solve(v1[i],v2[pos22-1],v3[pos3-1]));
}
}
}
}
cout<<minn<<endl;
}
return 0;
}
方法二:
#include<bits/stdc++.h>
#define ll long long
#define MOD 998244353
#define INF 0x3f3f3f3f
#define mem(a,x) memset(a,x,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
ll a[3][100005];
ll solve(ll i,ll j,ll k)
{
return (a[0][i]-a[1][j])*(a[0][i]-a[1][j])+(a[1][j]-a[2][k])*(a[1][j]-a[2][k])+(a[0][i]-a[2][k])*(a[0][i]-a[2][k]);
}
int main()
{
ll t;
cin>>t;
while(t--){
int cnt[3];
for(int i=0;i<3;i++)cin>>cnt[i];
for(int j=0;j<3;j++){
for(int i=0;i<cnt[j];i++){
scanf("%lld",&a[j][i]);
}
sort(a[j],a[j]+cnt[j]);
}
ll minn=INF;
ll i=0,j=0,k=0;
while(i<cnt[0]-1||j<cnt[1]-1||k<cnt[2]-1){
minn=min(minn,solve(i,j,k));
ll temp[3];
temp[0]=solve(i+1,j,k);
temp[1]=solve(i,j+1,k);
temp[2]=solve(i,j,k+1);
ll ans=INF;
if(i<cnt[0]-1) ans=min(ans,temp[0]);
if(j<cnt[1]-1) ans=min(ans,temp[1]);
if(k<cnt[2]-1) ans=min(ans,temp[2]);
if(temp[0]==ans&&i<cnt[0]-1) i++;
else if(temp[1]==ans&&j<cnt[1]-1) j++;
else if(temp[2]==ans&&k<cnt[2]-1) k++;
}
cout<<min(minn,solve(i,j,k))<<endl;
}
return 0;
}