Codeforces Round #635 (Div. 2)(D. Xenia and Colorful Gems)(训练)

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;
}

            

posted @ 2020-07-10 22:47  hachuochuo  阅读(85)  评论(0编辑  收藏  举报