Contar números formados por dos dígitos dados con suma que tiene dígitos dados

Dados a, b y N(1 a 10 6 ). La tarea es contar los números formados por los dígitos a y b exactamente de una longitud N tal que la suma de los dígitos del número así formado también contenga los dígitos a y b solamente. Dado que el conteo puede ser muy grande, imprima el conteo % 1000000007. 

Ejemplos: 

Input : a = 1 b = 3 n = 3 
Output : 1 
Explanation : The only number is 111 of length 3,
the sum of digits of 111 is 3, which is b. 

Input : a = 6 b = 9 n = 1
Output : 2
Explanation : The numbers of length 1 is 6 and 9,
whose sum of digits is 6 and 9 respectively which
is a and b respectively.

Input: a = 2 b = 3 n = 10
Output : 165   

Enfoque: dado que N es muy grande, no podemos iterar todos los números para verificarlos individualmente. Como el número es de longitud N y está formado por dos dígitos a y b, a ocupará i posiciones y b ocupará n – i posiciones. La suma de dígitos será así ( a*i + (ni)*b ) . Podemos comprobar si la suma de cifras está formada por a y b para todo i comprendido entre 0 y N. Así, la cuenta total de números formados será  {n \elegir yo}      la que corresponderá a toda combinación de números formada por a y b cuya suma de cifras también está formado por a y b. 

Implemente operaciones modulares en los cálculos: calcule 
{n \elegir yo}      1000000007 para todos los i que van de 0 a N y satisfacen la condición dada. 

Una solución simple dará respuesta como:  

(factorial(n) * modInverse(n - i) * modInverse(i)) % mod

Dado que el cálculo de modInverse toma O (log N), la complejidad de tiempo total será O (N log N), si todos los factoriales se calculan previamente. 

Una solución eficiente será precalcular todos los factoriales hasta N. ¡Calcula la modInversa de N! en O(log N) y calcule el modInverse de todos los factoriales de (N – 1)! ¡a 1! por la fórmula dada a continuación.  

modInverse(i!) = modInverse((i + 1)!) * (i + 1)

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

C++

// C++ program to count the number
// of numbers formed by digits a
// and b exactly of a length N such
// that the sum of the digits of the
// number thus formed is of digits a and b.
#include <bits/stdc++.h>
using namespace std;
 
const int mod = 1e9 + 7;
const int N = 1000005;
int fact[N], invfact[N];
 
// function to check if sum of
// digits is made of a and b
int check(int x, int a, int b)
{
    // sum of digits is 0
    if (x == 0)
        return 0;
 
    while (x) {
 
        // if any of digits in sum is
        // other than a and b
        if (x % 10 != a and x % 10 != b)
            return 0;
 
        x /= 10;
    }
 
    return 1;
}
 
// calculate the modInverse V / of a number in O(log n)
int modInverse(int a, int m)
{
    int m0 = m;
    int y = 0, x = 1;
 
    if (m == 1)
        return 0;
 
    while (a > 1) {
 
        // q is quotient
        int q = a / m;
        int t = m;
 
        // m is remainder now, process
        // same as Euclid's algo
        m = a % m, a = t;
        t = y;
 
        // Update y and x
        y = x - q * y;
        x = t;
    }
 
    // Make x positive
    if (x < 0)
        x += m0;
 
    return x;
}
 
// function to pregenerate factorials
void pregenFact()
{
    fact[0] = fact[1] = 1;
    for (int i = 1; i <= 1000000; ++i)
        fact[i] = (long long)fact[i - 1] * i % mod;
}
 
// function to pre calculate the
// modInverse of factorials
void pregenInverse()
{
    invfact[0] = invfact[1] = 1;
 
    // calculates the modInverse of the last factorial
    invfact[1000000] = modInverse(fact[1000000], mod);
 
    // precalculates the modInverse of all factorials
    // by formulae
    for (int i = 999999; i > 1; --i)
        invfact[i] = ((long long)invfact[i + 1] *
                      (long long)(i + 1)) % mod;
}
 
// function that returns the value of nCi
int comb(int big, int small)
{
    return (long long)fact[big] * invfact[small] % mod *
                              invfact[big - small] % mod;
}
 
// function that returns the count of numbers
int count(int a, int b, int n)
{
    // function call to pre-calculate the
    // factorials and modInverse of factorials
    pregenFact();
    pregenInverse();
 
    // if a and b are same
    if (a == b)
        return (check(a * n, a, b));
 
    int ans = 0;
    for (int i = 0; i <= n; ++i)
        if (check(i * a + (n - i) * b, a, b))
            ans = (ans + comb(n, i)) % mod;
    return ans;
}
 
// Driver Code
int main()
{
    int a = 3, b = 4, n = 11028;
    cout << count(a, b, n);
    return 0;
}

Java

// Java program to count the number
// of numbers formed by digits a
// and b exactly of a length N such
// that the sum of the digits of the
// number thus formed is of digits a and b.
 
class GFG
{
 
    static int mod = (int) (1e9 + 7);
    static int N = 1000005;
    static int fact[] = new int[N], invfact[] = new int[N];
 
    // function to check if sum of
    // digits is made of a and b
    static int check(int x, int a, int b)
    {
        // sum of digits is 0
        if (x == 0)
        {
            return 0;
        }
 
        while (x > 0)
        {
 
            // if any of digits in sum is
            // other than a and b
            if (x % 10 != a & x % 10 != b)
            {
                return 0;
            }
 
            x /= 10;
        }
 
        return 1;
    }
 
    // calculate the modInverse V / of a number in O(log n)
    static int modInverse(int a, int m)
    {
        int m0 = m;
        int y = 0, x = 1;
        if (m == 1)
        {
            return 0;
        }
 
        while (a > 1)
        {
 
            // q is quotient
            int q = a / m;
            int t = m;
 
            // m is remainder now, process
            // same as Euclid's algo
            m = a % m;
            a = t;
            t = y;
 
            // Update y and x
            y = x - q * y;
            x = t;
        }
 
        // Make x positive
        if (x < 0)
        {
            x += m0;
        }
 
        return x;
    }
 
    // function to pregenerate factorials
    static void pregenFact()
    {
        fact[0] = fact[1] = 1;
        for (int i = 1; i <= 1000000; ++i)
        {
            fact[i] = (int) ((long) fact[i - 1] * i % mod);
        }
    }
 
    // function to pre calculate the
    // modInverse of factorials
    static void pregenInverse()
    {
        invfact[0] = invfact[1] = 1;
 
        // calculates the modInverse of
        // the last factorial
        invfact[1000000] = modInverse(fact[1000000], mod);
 
        // precalculates the modInverse of
        // all factorials by formulae
        for (int i = 999999; i > 1; --i)
        {
            invfact[i] = (int) (((long) invfact[i + 1]
                    * (long) (i + 1)) % mod);
        }
    }
 
    // function that returns the value of nCi
    static int comb(int big, int small)
    {
        return (int) ((long) fact[big] * invfact[small] % mod
                * invfact[big - small] % mod);
    }
 
    // function that returns the count of numbers
    static int count(int a, int b, int n)
    {
         
        // function call to pre-calculate the
        // factorials and modInverse of factorials
        pregenFact();
        pregenInverse();
 
        // if a and b are same
        if (a == b)
        {
            return (check(a * n, a, b));
        }
 
        int ans = 0;
        for (int i = 0; i <= n; ++i)
        {
            if (check(i * a + (n - i) * b, a, b) == 1)
            {
                ans = (ans + comb(n, i)) % mod;
            }
        }
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int a = 3, b = 4, n = 11028;
        System.out.println(count(a, b, n));
    }
}
 
// This code is contributed by PrinciRaj1992

Python3

# Python 3 program to count the
# number of numbers formed by
# digits a and b exactly of a
# length N such that the sum of
# the digits of the number thus
# formed is of digits a and b.
 
mod = 1000000007
N = 1000005
fact = [0] * N
invfact = [0] * N
 
# function to check if sum of
# digits is made of a and b
def check(x, a, b):
 
    # sum of digits is 0
    if (x == 0):
        return 0
 
    while (x) :
 
        # if any of digits in sum
        # is other than a and b
        if (x % 10 != a and x % 10 != b):
            return 0
 
        x //= 10
 
    return 1
 
# calculate the modInverse V of
# a number in O(log n)
def modInverse(a, m):
 
    m0 = m
    y = 0
    x = 1
 
    if (m == 1):
        return 0
 
    while (a > 1) :
 
        # q is quotient
        q = a // m
        t = m
 
        # m is remainder now, process
        # same as Euclid's algo
        m = a % m
        a = t
        t = y
 
        # Update y and x
        y = x - q * y
        x = t
 
    # Make x positive
    if (x < 0):
        x += m0
 
    return x
 
# function to pregenerate factorials
def pregenFact():
 
    fact[0] = fact[1] = 1
    for i in range(1, 1000001):
        fact[i] = fact[i - 1] * i % mod
 
# function to pre calculate the
# modInverse of factorials
def pregenInverse():
     
    invfact[0] = invfact[1] = 1
 
    # calculates the modInverse of
    # the last factorial
    invfact[1000000] = modInverse(fact[1000000], mod)
 
    # precalculates the modInverse
    # of all factorials by formulae
    for i in range(999999, 0, -1):
        invfact[i] = ((invfact[i + 1] *
                      (i + 1)) % mod)
 
# function that returns
# the value of nCi
def comb(big, small):
     
    return (fact[big] * invfact[small] % mod *
                        invfact[big - small] % mod)
 
# function that returns the
# count of numbers
def count(a, b, n):
     
    # function call to pre-calculate
    # the factorials and modInverse
    # of factorials
    pregenFact()
    pregenInverse()
 
    # if a and b are same
    if (a == b) :
        return (check(a * n, a, b))
 
    ans = 0
    for i in range(n + 1) :
        if (check(i * a + (n - i) * b, a, b)) :
            ans = (ans + comb(n, i)) % mod
    return ans
 
# Driver Code
if __name__=="__main__":
    a = 3
    b = 4
    n = 11028
    print(count(a, b, n))
 
# This code is contributed
# by ChitraNayal

C#

// C# program to count the number
// of numbers formed by digits a
// and b exactly of a length N such
// that the sum of the digits of the
// number thus formed is of digits a and b.
using System;
 
class GFG
{
 
    static int mod = (int) (1e9 + 7);
    static int N = 1000005;
    static int []fact = new int[N];
    static int []invfact = new int[N];
 
    // function to check if sum of
    // digits is made of a and b
    static int check(int x, int a, int b)
    {
        // sum of digits is 0
        if (x == 0)
        {
            return 0;
        }
 
        while (x > 0)
        {
 
            // if any of digits in sum is
            // other than a and b
            if (x % 10 != a & x % 10 != b)
            {
                return 0;
            }
 
            x /= 10;
        }
 
        return 1;
    }
 
    // calculate the modInverse V / of a number in O(log n)
    static int modInverse(int a, int m)
    {
        int m0 = m;
        int y = 0, x = 1;
        if (m == 1)
        {
            return 0;
        }
 
        while (a > 1)
        {
 
            // q is quotient
            int q = a / m;
            int t = m;
 
            // m is remainder now, process
            // same as Euclid's algo
            m = a % m;
            a = t;
            t = y;
 
            // Update y and x
            y = x - q * y;
            x = t;
        }
 
        // Make x positive
        if (x < 0)
        {
            x += m0;
        }
 
        return x;
    }
 
    // function to pregenerate factorials
    static void pregenFact()
    {
        fact[0] = fact[1] = 1;
        for (int i = 1; i <= 1000000; ++i)
        {
            fact[i] = (int) ((long) fact[i - 1] * i % mod);
        }
    }
 
    // function to pre calculate the
    // modInverse of factorials
    static void pregenInverse()
    {
        invfact[0] = invfact[1] = 1;
 
        // calculates the modInverse of
        // the last factorial
        invfact[1000000] = modInverse(fact[1000000], mod);
 
        // precalculates the modInverse of
        // all factorials by formulae
        for (int i = 999999; i > 1; --i)
        {
            invfact[i] = (int) (((long) invfact[i + 1]
                    * (long) (i + 1)) % mod);
        }
    }
 
    // function that returns the value of nCi
    static int comb(int big, int small)
    {
        return (int) ((long) fact[big] * invfact[small] % mod
                * invfact[big - small] % mod);
    }
 
    // function that returns the count of numbers
    static int count(int a, int b, int n)
    {
         
        // function call to pre-calculate the
        // factorials and modInverse of factorials
        pregenFact();
        pregenInverse();
 
        // if a and b are same
        if (a == b)
        {
            return (check(a * n, a, b));
        }
 
        int ans = 0;
        for (int i = 0; i <= n; ++i)
        {
            if (check(i * a + (n - i) * b, a, b) == 1)
            {
                ans = (ans + comb(n, i)) % mod;
            }
        }
        return ans;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int a = 3, b = 4, n = 11028;
        Console.WriteLine(count(a, b, n));
    }
}
 
// This code has been contributed by 29AjayKumar

Javascript

<script>
    // JavaScript program to count the number
    // of numbers formed by digits a
    // and b exactly of a length N such
    // that the sum of the digits of the
    // number thus formed is of digits a and b.
    const mod = 1000000007;
    const N = 1000005;
    let fact = new Array(N).fill(0);
    let invfact = new Array(N).fill(0);
 
    // function to check if sum of
    // digits is made of a and b
    const check = (x, a, b) => {
     
        // sum of digits is 0
        if (x == 0)
            return 0;
 
        while (x) {
 
            // if any of digits in sum is
            // other than a and b
            if (x % 10 != a && x % 10 != b)
                return 0;
 
            x = Math.floor(x / 10);
        }
 
        return 1;
    }
 
    // calculate the modInverse V / of a number in O(log n)
    const modInverse = (a, m) => {
        let m0 = m;
        let y = 0, x = 1;
 
        if (m == 1)
            return 0;
 
        while (a > 1) {
 
            // q is quotient
            let q = Math.floor(a / m);
            let t = m;
 
            // m is remainder now, process
            // same as Euclid's algo
            m = a % m;
            a = t;
            t = y;
 
            // Update y and x
            y = x - q * y;
            x = t;
        }
 
        // Make x positive
        if (x < 0)
            x += m0;
 
        return x;
    }
 
    // function to pregenerate factorials
    const pregenFact = () => {
        fact[0] = 1;
        fact[1] = 1;
        for (let i = 1; i <= 1000000; ++i)
            fact[i] = fact[i - 1] * i % mod;
    }
 
    // function to pre calculate the
    // modInverse of factorials
    const pregenInverse = () => {
        invfact[0] = 1;
        invfact[1] = 1;
 
        // calculates the modInverse of the last factorial
        invfact[1000000] = modInverse(fact[1000000], mod);
 
        // precalculates the modInverse of all factorials
        // by formulae
        for (let i = 999999; i > 1; --i)
            invfact[i] = (invfact[i + 1] * (i + 1)) % mod;
    }
 
    // function that returns the value of nCi
    let comb = (big, small) => {
        return ((BigInt(fact[big]) * BigInt(invfact[small])) % BigInt(mod) * BigInt(invfact[big - small]) % BigInt(mod)) % BigInt(mod);
    }
 
    // function that returns the count of numbers
    const count = (a, b, n) => {
     
        // function call to pre-calculate the
        // factorials and modInverse of factorials
        pregenFact();
        pregenInverse();
 
        // if a and b are same
        if (a == b)
            return (check(a * n, a, b));
 
        let ans = 0n;
        for (let i = 0; i <= n; ++i)
            if (check(i * a + (n - i) * b, a, b)) {
                ans = (ans + comb(n, i)) % BigInt(mod);
            }
        return ans;
    }
 
    // Driver Code
    let a = 3, b = 4, n = 11028;
    document.write(count(a, b, n));
 
// This code is contributed by rakeshsahni
 
</script>
Producción: 

461668105

 

Publicación traducida automáticamente

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