Programación pensamiento semana 4 tarea tarea serie B

Titulo

ZJM tiene cuatro series A, B, C, D, cada serie tiene n números. ZJM toma un número de cada secuencia y quiere saber cuántos esquemas hacen que la suma de los cuatro números sea cero.
Cuando hay varios números idénticos en una secuencia, trátelos como números diferentes.

Entrada

La primera fila: n (que representa el número de números en la secuencia) (1≤n≤4000).
En las siguientes n filas, la fila i-ésima tiene cuatro números, que representan el número i-ésimo en la secuencia A, B, C, D (el número no excede la potencia 28 de 2).

Salida

Se emite el número de combinaciones diferentes.

Entrada de muestra

6
-45 22 42 -16
-41 -27 56 30
-36 53 -37 77
-36 30 -75 -46
26 -38 -10 62
-32 -54 -6 45

Salida de muestra

5

Ideas

Si los números en ABCD se enumeran directamente, la complejidad es O (n ^ 4) y la complejidad es demasiado alta. La idea es calcular A + B + C + D = 0.
Para reducir los puntos de enumeración y reducir la complejidad, puede enumerar A y B, y luego enumerar C y D, la complejidad es O (n ^ 2). La idea de hacer esto es calcular A + B = - (C + D).
Primero enumere A y B, calcule la suma de A + B y almacénelo en la matriz e [], y conviértalo en una matriz ordenada. Luego enumere C y D, y calcule cuántas veces aparece lo opuesto de C + D en e []. Al calcular cuántas veces ocurre lo contrario, se usa la dicotomía.
Al realizar la dicotomía, los límites izquierdo y derecho l y r toman respectivamente los límites izquierdo y derecho de la matriz e [], cuando l <r, loop, tome el valor en la posición de mid = (l + r) / 2, si es el valor que está buscando, verifique Si sus valores izquierdo y derecho son también el valor que está buscando, hasta que encuentre todos los puntos que cumplan con sus requisitos y devuelva el número de puntos encontrados; si es menor que el valor que desea, l se actualiza a mediados + 1; si es mayor que el valor que desea, r se actualiza a mediados de 1.

Código

#include <cstdio>
#include <algorithm>
using namespace std;

int a[4005],b[4005],c[4005],d[4005],e[4000*4000+5];
int n;

int find(int x){
    int l=0,r=n*n,leftx=0,rightx=0;
    while(l<=r){
        int mid=(l+r)/2;
        if(e[mid]==x){
            while((mid+rightx)<n*n&&e[mid+rightx]==x){
                rightx++;
            }
            while((mid-leftx)>=0&&e[mid-leftx]==x){
                leftx++;
            }
            return leftx+rightx-1;
        }
        else if(e[mid]<x)
            l=mid+1;
        else if(e[mid]>x)
            r=mid-1;
    }
    return 0;
}

int main() {
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
    }
    int k=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            e[k]=a[i]+b[j];
            k++;
        }
    }
    int sum=0;
    sort(e,e+n*n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            sum+=find(-(c[i]+d[j]));
        }
    }
    printf("%d",sum);
    return 0;
}

Enlace del título

Publicado 24 artículos originales · elogiado 2 · visitas 435

Supongo que te gusta

Origin blog.csdn.net/weixin_43805228/article/details/104978161
Recomendado
Clasificación