Codeforces 1336B / 1337D-Xenia e gemas coloridas (dois pontos / pensamento)


Título

Prob




Título

Dadas três matrizes

Requer um número de cada matriz

Peça o mínimo da soma dos quadrados da diferença entre esses três números




Ideias de resolução de problemas

Embora seja uma ideia, é realmente uma bagunça

O seguinte pode parecer um pouco confuso


Para esse tipo de problema, conheço apenas uma conclusão:

Se dois números ab foram corrigidos, e o terceiro número c é garantido entre esses dois números

Então, o valor mínimo pode ser obtido quando c estiver no meio de ab. Se c estiver próximo a um dos lados de a ou b, o valor da resposta será maior (semelhante à imagem da função quadrática que se abre para cima)


Então, minha ideia é enumerar o primeiro número na primeira matriz R , com o subscrito i (todos os subscritos começam em 0, a matriz foi classificada de pequena a grande)

Encontre o primeiro número maior ou igual a R [i] na segunda matriz G por pesquisa binária, com o subscrito gtmp

Em seguida, os únicos subscritos possíveis são gtmp (maior ou igual a R [i]) e gtmp-1 (menor que R [i]) (se existir)

Considere os dois casos, aqui está o gtmp como exemplo

Agora nós fixamos os dois números R [i] e G [gtmp]

De acordo com a conclusão acima, devemos encontrar o número mais próximo de (R [i] + G [gtmp]) / 2 na terceira matriz

Na mesma pesquisa binária, obtenha o primeiro subscrito maior ou igual a esse número, definido como btmp

Portanto, os possíveis subscritos na terceira matriz são btmp e btmp-1

Vamos usar o btmp como exemplo

Neste momento, você pode usar R [i] / G [gtmp] / B [btmp] para calcular a resposta uma vez e fazer as pequenas

Mas também é possível que isso aconteça.

Quando procuramos btmp no binário acima, usamos (R [i] + G [gtmp]) / 2 como a pesquisa de índice, portanto assumimos que R [i] e G [gtmp] contêm o mínimo e o máximo desses três números. Valor e B [btmp] devem estar dentro desses dois valores

De fato, pode acontecer que B [btmp] esteja fora de R [i] ~ G [gtmp]

(Essa situação ocorre nos dois exemplos do 4º e 5º. Tomando o 4º exemplo como exemplo, o primeiro número é enumerado em 2 e o número mais próximo na segunda matriz é 3 , O terceiro número mais próximo dividido por (2 + 3) / 2 = 2 é 6, é fácil descobrir que 6 excedeu o intervalo de 2 ~ 3 e se 6 é o valor máximo, na verdade o primeiro O valor mínimo da resposta só pode ser obtido quando os dois números são 4)

Portanto, mantemos o subscrito i da primeira matriz R fixo, consideramos gtmp neste momento como o maior valor e usamos (R [i] + B [btmp]) / 2 como a dicotomia de índice na segunda matriz novamente Obtenha o novo subscrito gtmp2

Da mesma forma, use gtmp2 ou gtmp2-1 como o subscrito da segunda matriz e, em seguida, calcule e aceite a resposta novamente para considerar o processo completo.

O acima é apenas uma bagunça de idéias, consulte o código para obter detalhes




Programa completo

A maioria deles é realmente copiar e colar

(Pré-testes: 186ms / 3000ms)

(Testes do sistema: 233ms / 3000ms)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll LINF=0x3f3f3f3f3f3f3f3f;

ll R[100050],G[100050],B[100050];

inline ll cal(ll a,ll b,ll c)
{
    return (a-b)*(a-b)+(a-c)*(a-c)+(b-c)*(b-c);
}

void solve()
{
    int nr,ng,nb;
    cin>>nr>>ng>>nb;

    for(int i=0;i<nr;i++)
        cin>>R[i];
    for(int i=0;i<ng;i++)
        cin>>G[i];
    for(int i=0;i<nb;i++)
        cin>>B[i];
    sort(R,R+nr);
    sort(G,G+ng);
    sort(B,B+nb);

    ll ans=LINF;
    int gtmp,btmp,gtmp2;
    for(int i=0;i<nr;i++) //枚举第一个数组中的下标 i
    {
        gtmp=lower_bound(G,G+ng,R[i])-G; //以R[i]为索引二分查找第二个数组中第一个大于等于的数字下标
        if(gtmp<ng) //gtmp下标如果合法
        {
            btmp=lower_bound(B,B+nb,(R[i]+G[gtmp])>>1)-B; //以(R[i]+G[gtmp])/2为索引二分第三个数字下标btmp
            if(btmp<nb) //btmp下标如果合法
            {
                ans=min(ans,cal(R[i],G[gtmp],B[btmp])); //计算一次此时的答案
                gtmp2=lower_bound(G,G+ng,(R[i]+B[btmp])>>1)-G; //固定i和btmp,以(R[i]+B[btmp])/2为索引重新二分寻找第二个数字下标gtmp2
                if(gtmp2<ng)
                    ans=min(ans,cal(R[i],G[gtmp2],B[btmp])); //合法时计算答案,下同
                if(gtmp2>0)
                    ans=min(ans,cal(R[i],G[gtmp2-1],B[btmp]));
            }
            if(btmp>0) //btmp-1下标如果合法
            {
                ans=min(ans,cal(R[i],G[gtmp],B[btmp-1]));
                gtmp2=lower_bound(G,G+ng,(R[i]+B[btmp-1])>>1)-G;
                if(gtmp2<ng)
                    ans=min(ans,cal(R[i],G[gtmp2],B[btmp-1]));
                if(gtmp2>0)
                    ans=min(ans,cal(R[i],G[gtmp2-1],B[btmp-1]));
            }
        }
        if(gtmp>0)//gtmp-1下标如果合法
        {
            btmp=lower_bound(B,B+nb,(R[i]+G[gtmp-1])>>1)-B;
            if(btmp<nb)
            {
                ans=min(ans,cal(R[i],G[gtmp-1],B[btmp]));
                gtmp2=lower_bound(G,G+ng,(R[i]+B[btmp])>>1)-G;
                if(gtmp2<ng)
                    ans=min(ans,cal(R[i],G[gtmp2],B[btmp]));
                if(gtmp2>0)
                    ans=min(ans,cal(R[i],G[gtmp2-1],B[btmp]));
            }
            if(btmp>0)
            {
                ans=min(ans,cal(R[i],G[gtmp-1],B[btmp-1]));
                gtmp2=lower_bound(G,G+ng,(R[i]+B[btmp-1])>>1)-G;
                if(gtmp2<ng)
                    ans=min(ans,cal(R[i],G[gtmp2],B[btmp-1]));
                if(gtmp2>0)
                    ans=min(ans,cal(R[i],G[gtmp2-1],B[btmp-1]));
            }
        }
    }
    cout<<ans<<'\n';
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;cin>>T;
    for(int t=1;t<=T;t++)
        solve();
    return 0;
}

Acho que você gosta

Origin www.cnblogs.com/stelayuri/p/12709971.html
Recomendado
Clasificación