Encuentra la posición del elemento en una secuencia monótona dada

Dado un entero k y una secuencia monótona creciente: 
f(n) = an + bn [log2(n)] + cn^3 donde ( a = 1, 2, 3, …), ( b = 1, 2, 3, …), ( c = 0, 1, 2, 3, …) 
Aquí, [log 2 (n)] significa llevar el logaritmo a la base 2 y redondear el valor hacia abajo. Por lo tanto, 
si n = 1, el valor es 0
Si n = 2-3, el valor es 1.  Si 
n = 4-7, el valor es 2. 
Si n = 8-15, el valor es 3. 
La tarea es encontrar el valor n tal que f(n ) = k , si k no pertenece a la secuencia, imprima 0

Nota: Los valores están de tal forma que se pueden expresar en 64 bits y los tres enteros a, b y c no superan 100.

Ejemplos: 

Entrada: a = 2, b = 1, c = 1, k = 12168587437017 
Salida: 23001 
f(23001) = 12168587437017

Entrada: a = 7, b = 3, c = 0, k = 119753085330 
Salida: 1234567890 

Enfoque ingenuo: valores dados de a, b, c, encontrar valores de f(n) para cada valor de n y compararlos.

Enfoque eficiente: utilice la búsqueda binaria, elija n = (mín. + máx.) / 2, donde mín . y máx . son los valores mínimo y máximo posibles para n , luego,  

  • Si f(n) < k entonces incrementa n .
  • Si f(n) > k entonces decrementa n .
  • Si f(n) = k entonces n es la respuesta requerida.
  • Repita los pasos anteriores hasta que se encuentre el valor requerido o no sea posible en la secuencia.

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

C++

// C++ implementation of the approach
#include <iostream>
#include <math.h>
#define SMALL_N 1000000
#define LARGE_N  1000000000000000
using namespace std;
 
// Function to return the value of f(n) for given values of a, b, c, n
long long func(long long a, long long b, long long c, long long n)
{
    long long res = a * n;
    long long logVlaue = floor(log2(n));
    res += b * n * logVlaue;
    res += c * (n * n * n);
    return res;
}
 
long long getPositionInSeries(long long a, long long b,
                             long long c, long long k)
{
    long long start = 1, end = SMALL_N;
 
    // if c is 0, then value of n can be in order of 10^15.
    // if c!=0, then n^3 value has to be in order of 10^18
    // so maximum value of n can be 10^6.
    if (c == 0) {
        end = LARGE_N;
    }
    long long ans = 0;
 
    // for efficient searching, use binary search.
    while (start <= end) {
        long long mid = (start + end) / 2;
        long long val = func(a, b, c, mid);
        if (val == k) {
            ans = mid;
            break;
        }
        else if (val > k) {
            end = mid - 1;
        }
        else {
            start = mid + 1;
        }
    }
    return ans;
}
 
// Driver code
int main()
{
    long long a = 2, b = 1, c = 1;
    long long k = 12168587437017;
 
    cout << getPositionInSeries(a, b, c, k);
 
    return 0;
}

Python3

# Python 3 implementation of the approach
from math import log2, floor
SMALL_N = 1000000
LARGE_N = 1000000000000000
 
# Function to return the value of f(n)
# for given values of a, b, c, n
def func(a, b, c, n) :
     
    res = a * n
    logVlaue = floor(log2(n))
    res += b * n * logVlaue
    res += c * (n * n * n)
    return res
 
def getPositionInSeries(a, b, c, k) :
     
    start = 1
    end = SMALL_N
 
    # if c is 0, then value of n
    # can be in order of 10^15.
    # if c!=0, then n^3 value has
    # to be in order of 10^18
    # so maximum value of n can be 10^6.
    if (c == 0) :
        end = LARGE_N
     
    ans = 0
 
    # for efficient searching,
    # use binary search.
    while (start <= end) :
         
        mid = (start + end) // 2
        val = func(a, b, c, mid)
        if (val == k) :
            ans = mid
            break
     
        elif (val > k) :
            end = mid - 1
 
        else :
            start = mid + 1
         
    return ans;
 
# Driver code
if __name__ == "__main__" :
     
    a = 2
    b = 1
    c = 1
    k = 12168587437017
 
    print(getPositionInSeries(a, b, c, k))
 
# This code is contributed by Ryuga

PHP

<?php
// PHP implementation of the approach
// from math import log2, floor
$SMALL_N = 1000000;
$LARGE_N = 1000000000000000;
 
// Function to return the value of f(n)
// for given values of a, b, c, n
function func($a, $b, $c, $n)
{
    $res = $a * $n;
    $logVlaue = floor(log($n, 2));
    $res += $b * $n * $logVlaue;
    $res += $c * ($n * $n * $n);
    return $res;
}
 
function getPositionInSeries($a, $b, $c, $k)
{
    global $SMALL_N, $LARGE_N;
    $start = 1;
    $end = $SMALL_N;
 
    // if c is 0, then value of n
    // can be in order of 10^15.
    // if c!=0, then n^3 value has
    // to be in order of 10^18
    // so maximum value of n can be 10^6.
    if ($c == 0)
        $end = $LARGE_N;
     
    $ans = 0;
 
    // for efficient searching,
    // use binary search.
    while ($start <= $end)
    {
        $mid = (int)(($start + $end) / 2);
        $val = func($a, $b, $c, $mid) ;
        if ($val == $k)
        {
            $ans = $mid;
            break;
        }
     
        else if ($val > $k)
            $end = $mid - 1;
 
        else
            $start = $mid + 1;
    }
    return $ans;
}
 
// Driver code
$a = 2;
$b = 1;
$c = 1;
$k = 12168587437017;
 
print(getPositionInSeries($a, $b, $c, $k));
 
// This code is contributed by mits
?>

Javascript

<script>
 
// Javascript implementation of the approach
const SMALL_N = 1000000;
const LARGE_N = 1000000000000000;
 
// Function to return the value of f(n)
// for given values of a, b, c, n
function func(a, b, c, n)
{
    let res = a * n;
    let logVlaue = Math.floor(Math.log(n) /
                              Math.log(2));
    res += b * n * logVlaue;
    res += c * (n * n * n);
    return res;
}
 
function getPositionInSeries(a, b, c, k)
{
    let start = 1, end = SMALL_N;
 
    // If c is 0, then value of n can be
    // in order of 10^15. If c!=0, then
    // n^3 value has to be in order of 10^18
    // so maximum value of n can be 10^6.
    if (c == 0)
    {
        end = LARGE_N;
    }
    let ans = 0;
 
    // For efficient searching, use binary search.
    while (start <= end)
    {
        let mid = parseInt((start + end) / 2);
        let val = func(a, b, c, mid);
        if (val == k)
        {
            ans = mid;
            break;
        }
        else if (val > k)
        {
            end = mid - 1;
        }
        else
        {
            start = mid + 1;
        }
    }
    return ans;
}
 
// Driver code
let a = 2, b = 1, c = 1;
let k = 12168587437017;
 
document.write(getPositionInSeries(a, b, c, k));
 
// This code is contributed by souravmahato348
 
</script>
Producción: 

23001

 

Complejidad Temporal: O(log n), ya que es una búsqueda binaria donde cada vez los elementos se reducen a la mitad.
Espacio Auxiliar: O(1), ya que no se ha ocupado ningún espacio extra.

Publicación traducida automáticamente

Artículo escrito por _amit 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 *