Suma de la división de los pares posibles para el Array dado

Dada una array arr[] de N enteros positivos. Para todos los pares posibles (x, y) la tarea es encontrar la sumatoria de x/y .
Nota: si la parte decimal de (x/y) es &ge 0.5, agregue el techo de (x/y) , de lo contrario, agregue el piso de (x/y) .
Ejemplos: 
 

Entrada: arr[] = {1, 2, 3} 
Salida: 12 
Explicación: 
Todos los pares posibles con división son: 
(1/1) = 1, (1/2) = 1, (1/3) = 0 
(2 /1) = 2, (2/2) = 1, (2/3) = 1 
(3/1) = 3, (3/2) = 2, (3/3) = 1 
Suma = 1 + 1 + 0 + 2 + 1 + 1 + 3 + 2 + 1 = 12.
Entrada: arr[] = {1, 2, 3, 4} 
Salida: 22 
Explicación: 
Todos los pares posibles con división son: 
(1/1) = 1 , (1/2) = 1, (1/3) = 0, (1/4) = 0 
(2/1) = 2, (2/2) = 1, (2/3) = 1, (2 /4) = 1 
(3/1) = 3, (3/2) = 2, (3/3) = 1, (3/4) = 1 
(4/1) = 4, (4/2) = 2, (4/3) = 1, (4/4) = 1 
Suma = 1 + 1 + 0 + 0 + 2 + 1 + 1 + 1 + 3 + 2 + 1 + 1 + 4 + 2 + 1 + 1 = 22. 
 

Enfoque ingenuo: la idea es generar todos los pares posibles en la array dada y encontrar la suma de (x/y) para cada par (x, y) .
Complejidad de tiempo: O(N 2 )
Enfoque eficiente:
Para optimizar el método anterior, tenemos que calcular la array de frecuencias donde freq[i] denota el número de ocurrencias del número i. 
 

  • Para cualquier número X dado, todos los números que van desde [0.5X, 1.5X] contribuirían con 1 a la respuesta cuando se dividen por X. De manera similar, todos los números que van desde [1.5X, 2.5X] contribuirían con 2 a la respuesta cuando se divide por X.
  • Generalizando este hecho, todos los números que van desde [(n-0.5)X, (n+0.5)X] contribuirían con n a la respuesta cuando se divide por X.
  • Por lo tanto, para cada número P en el rango de 1 a N, podemos obtener el recuento de los números que se encuentran en el rango dado [L, R] simplemente calculando una suma de prefijos de la array de frecuencias.
  • Para un número P, necesitamos consultar los rangos en la mayoría de los tiempos N/P.

A continuación se muestra la implementación del enfoque anterior: 
 

C++

// C++ implementation to compute the
// sum of division of all the possible
// pairs for the given array
 
#include <bits/stdc++.h>
#define ll long long
using namespace std;
 
// Function to compute the sum
int func(int arr[], int n)
{
 
    double ans = 0;
    int maxx = 0;
    double freq[100005] = { 0 };
    int temp;
 
    // counting frequency
    // of each term
    // and finding maximum
    // among it
    for (int i = 0; i < n; i++) {
        temp = arr[i];
        freq[temp]++;
        maxx = max(maxx, temp);
    }
 
    // Making cumulative frequency
    for (int i = 1; i <= maxx; i++) {
        freq[i] += freq[i - 1];
    }
 
    for (int i = 1; i <= maxx; i++) {
        if (freq[i]) {
            i = (double)i;
            double j;
            ll value = 0;
 
            // Taking the ceil value
            double cur = ceil(0.5 * i) - 1.0;
 
            for (j = 1.5;; j++) {
                int val = min(maxx, (int)(ceil(i * j) - 1.0));
                int times = (freq[i] - freq[i - 1]), con = j - 0.5;
 
                // nos. in [(n-0.5)X, (n+0.5)X)
                // range will add n to the ans
 
                ans += times * con * (freq[(int)val] - freq[(int)cur]);
                cur = val;
 
                if (val == maxx)
                    break;
            }
        }
    }
 
    // Return the final result
    return (ll)ans;
}
 
// Driver code
int main()
{
    int arr[] = { 1, 2, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    cout << func(arr, n) << endl;
 
    return 0;
}

Java

// Java implementation to compute the
// sum of division of all the possible
// pairs for the given array
class GFG{
 
// Function to compute the sum
static long func(int arr[], int n)
{
    double ans = 0;
    int maxx = 0;
    double freq[] = new double[100005];
    int temp;
 
    // Counting frequency of each term
    // and finding maximum among it
    for(int i = 0; i < n; i++)
    {
       temp = arr[i];
       freq[temp]++;
       maxx = Math.max(maxx, temp);
    }
 
    // Making cumulative frequency
    for(int i = 1; i <= maxx; i++)
    {
       freq[i] += freq[i - 1];
    }
 
    for(int i = 1; i <= maxx; i++)
    {
       if (freq[i] != 0)
       {
           double j;
            
           // Taking the ceil value
           double cur = Math.ceil(0.5 * i) - 1.0;
            
           for(j = 1.5;; j++)
           {
              int val = Math.min(maxx,
                  (int)(Math.ceil(i * j) - 1.0));
              int times = (int)(freq[i] -
                                freq[i - 1]),
                    con = (int)(j - 0.5);
               
              // nos. in [(n-0.5)X, (n+0.5)X)
              // range will add n to the ans
              ans += times * con * (freq[(int)val] -
                                    freq[(int)cur]);
              cur = val;
              
              if (val == maxx)
                  break;
           }
       }
    }
     
    // Return the final result
    return (long)ans;
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 3 };
    int n = arr.length;
 
    System.out.print(func(arr, n) + "\n");
}
}
 
// This code is contributed by Amit Katiyar

Python3

# Python3 program to compute the sum
# of division of all the possible
# pairs for the given array
from math import *
 
# Function to compute the sum
def func (arr, n):
 
    ans = 0
    maxx = 0
    freq = [0] * 100005
    temp = 0
 
    # Counting frequency of each term
    # and finding maximum among it
    for i in range(n):
        temp = arr[i]
        freq[temp] += 1
        maxx = max(maxx, temp)
 
    # Making cumulative frequency
    for i in range(1, maxx + 1):
        freq[i] += freq[i - 1]
 
    for i in range(1, maxx + 1):
        if (freq[i]):
            value = 0
 
            # Taking the ceil value
            cur = ceil(0.5 * i) - 1.0
 
            j = 1.5
            while (1):
                val = min(maxx, (ceil(i * j) - 1.0))
                times = (freq[i] - freq[i - 1])
                con = j - 0.5
 
                # nos. in [(n-0.5)X , (n+0.5)X)
                # range will add n to the ans
                ans += times * con * (freq[int(val)] -
                                      freq[int(cur)])
                cur = val
 
                if (val == maxx):
                    break
                j += 1
 
    return int(ans)
 
# Driver code
if __name__ == '__main__':
 
    arr = [ 1, 2, 3 ]
    n = len(arr)
 
    print(func(arr, n))
 
# This code is contributed by himanshu77

C#

// C# implementation to compute the
// sum of division of all the possible
// pairs for the given array
using System;
 
class GFG{
 
// Function to compute the sum
static long func(int []arr, int n)
{
    double ans = 0;
    int maxx = 0;
    double []freq = new double[100005];
    int temp;
 
    // Counting frequency of each term
    // and finding maximum among it
    for(int i = 0; i < n; i++)
    {
       temp = arr[i];
       freq[temp]++;
       maxx = Math.Max(maxx, temp);
    }
 
    // Making cumulative frequency
    for(int i = 1; i <= maxx; i++)
    {
       freq[i] += freq[i - 1];
    }
 
    for(int i = 1; i <= maxx; i++)
    {
       if (freq[i] != 0)
       {
           double j;
            
           // Taking the ceil value
           double cur = Math.Ceiling(0.5 * i) - 1.0;
            
           for(j = 1.5;; j++)
           {
              int val = Math.Min(maxx,
                  (int)(Math.Ceiling(i * j) - 1.0));
              int times = (int)(freq[i] -
                                freq[i - 1]),
                    con = (int)(j - 0.5);
                     
              // nos. in [(n-0.5)X, (n+0.5)X)
              // range will add n to the ans
              ans += times * con * (freq[(int)val] -
                                    freq[(int)cur]);
              cur = val;
               
              if (val == maxx)
                  break;
           }
       }
    }
     
    // Return the readonly result
    return (long)ans;
}
 
// Driver code
public static void Main(String[] args)
{
    int []arr = { 1, 2, 3 };
    int n = arr.Length;
 
    Console.Write(func(arr, n) + "\n");
}
}
 
// This code is contributed by Amit Katiyar

Javascript

<script>
 
// JavaScript implementation to compute the
// sum of division of all the possible
// pairs for the given array
 
// Function to compute the sum
function func(arr, n)
{
    let ans = 0;
    let maxx = 0;
    let freq = Array.from({length: 100005}, (_, i) => 0);
    let temp;
   
    // Counting frequency of each term
    // and finding maximum among it
    for(let i = 0; i < n; i++)
    {
       temp = arr[i];
       freq[temp]++;
       maxx = Math.max(maxx, temp);
    }
   
    // Making cumulative frequency
    for(let i = 1; i <= maxx; i++)
    {
       freq[i] += freq[i - 1];
    }
   
    for(let i = 1; i <= maxx; i++)
    {
       if (freq[i] != 0)
       {
           let j;
              
           // Taking the ceil value
           let cur = Math.ceil(0.5 * i) - 1.0;
              
           for(j = 1.5;; j++)
           {
              let val = Math.min(maxx,
                  (Math.ceil(i * j) - 1.0));
              let times = (freq[i] -
                                freq[i - 1]),
                    con = (j - 0.5);
                 
              // nos. in [(n-0.5)X, (n+0.5)X)
              // range will add n to the ans
              ans += times * con * (freq[val] -
                                    freq[cur]);
              cur = val;
                
              if (val == maxx)
                  break;
           }
       }
    }
       
    // Return the final result
    return ans;
}
   
    
 
// Driver Code
 
     let arr = [ 1, 2, 3 ];
    let n = arr.length;
   
    document.write(func(arr, n));
           
</script>
Producción: 

12

 

Complejidad de tiempo: O(N * log (N) ) , donde N representa el tamaño de la array dada.
 Espacio auxiliar: O(100005) , no se requiere espacio adicional, por lo que es una constante.

Publicación traducida automáticamente

Artículo escrito por KrishnaHare y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *