Open In App

Count integers with specific Digit Sum property

Last Updated : 04 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given 5 integers N, A, B, C, D.  Let us say all the integers of length N, have only A or B in their decimal representation. Also, among all these numbers, all the numbers whose decimal representation of the sum of digits of the number contains either C or D or both as one or more digits in the decimal representation of the sum of number, we have to return the count of such numbers. Since the number of these integers can be huge, print it modulo 109+7.

Note: 1 ≤ A, B, C, D ≤ 9

Examples:

Input: N = 2, A = 1, B = 2, C = 3, D = 5
Output: 2
Explanation: The following are good integers: { 12, 22, 11, 21 }
And the following are the best integers: { 12, 21 } because the sum of digits of 11, 22 are 2 and 4, they are not equal to C or D.

Input: N = 1, A = 1, B = 1, C = 2, D = 3
Output: 0
Explanation: The following are good integers: – { 1 }
Since the sum of digits is 1 which is not equal to C or D, therefore, the answer is 0.

Approach: This problem can be solved using Permutations and Combinations.

If the current sum has i A’s then it will have N-i B’s. If this sum has only C’s and D’s, then for this sum the number of distinct possible numbers of N length is equal to NCI, where C is the number of combinations.

Steps that were to follow the above approach:

  • Precompute all factorials and inverse factorials.
  • If A and B are equal then just check if there exists at least one digit in the sum that is C or D. If it does return 1 else return 0.
  • Iterate from 0 till N taking the number of A as i and B as N-i and check if their sum has at least one digit as C or D in its representation. If it has, add NCi to the answer.

Below is the implementation of the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
int done = 0;
vector<long long> f, inv;
class Solution {
    const long long M = 1e9 + 7;
 
public:
    int bestNumbers(int N, int A, int B, int C, int D)
    {
        if (!done)
            pre();
        if (A == B) {
            long long sum = (long long)N * A;
            bool flag = false;
            while (sum > 0) {
                if ((sum % 10) == C or (sum % 10) == D) {
                    flag = true;
                    break;
                }
                sum /= 10;
            }
            if (flag)
                return 1;
            return 0;
        }
        long long ans = 0;
        for (long long i = 0; i <= N; i++) {
            long long sum = i * A + (N - i) * B;
            bool flag = false;
            while (sum > 0) {
                if ((sum % 10) == C or (sum % 10) == D) {
                    flag = true;
                    break;
                }
                sum /= 10;
            }
            if (flag)
                ans = (ans + nCr(N, i)) % M;
        }
        return ans;
    }
    void pre()
    {
        done = 1;
        f.resize(1e5 + 1, 1);
        inv.resize(1e5 + 1);
        for (int i = 2; i <= 1e5; i++)
            f[i] = (f[i - 1] * i) % M;
        inv[1e5] = fastpow(f[1e5], M - 2);
        for (int i = 1e5 - 1; i >= 0; i--)
            inv[i] = (inv[i + 1] * (i + 1)) % M;
    }
    long long fastpow(long long a, long long n)
    {
        long long res = 1;
        while (n > 0) {
            if (n & 1)
                res = (res * a) % M;
            a = (a * a) % M;
            n >>= 1;
        }
        return res;
    }
    long long nCr(int n, int r)
    {
        return (((f[n] * inv[n - r]) % M) * inv[r]) % M;
    }
};
 
// Driver's code
int main()
{
 
    Solution obj;
 
    int N = 2, A = 1, B = 2, C = 3, D = 5;
 
    // Function Call
    cout << obj.bestNumbers(N, A, B, C, D);
 
    return 0;
}


Java




// Java code for the above approach
import java.util.Arrays;
 
public class GFG {
 
    private static final long M = 1000000007;
 
    private static long[] f;
    private static long[] inv;
 
    public static int bestNumbers(int N, int A, int B, int C, int D) {
        if (A == B) {
            long sum = (long) N * A;
            boolean flag = false;
            while (sum > 0) {
                if ((sum % 10) == C || (sum % 10) == D) {
                    flag = true;
                    break;
                }
                sum /= 10;
            }
            if (flag) return 1;
            return 0;
        }
        long ans = 0;
        for (long i = 0; i <= N; i++) {
            long sum = i * A + (N - i) * B;
            boolean flag = false;
            while (sum > 0) {
                if ((sum % 10) == C || (sum % 10) == D) {
                    flag = true;
                    break;
                }
                sum /= 10;
            }
            if (flag) ans = (ans + nCr(N, (int) i)) % M;
        }
        return (int) ans;
    }
 
    static {
        f = new long[100001];
        inv = new long[100001];
        f[0] = 1;
        for (int i = 1; i <= 100000; i++) {
            f[i] = (f[i - 1] * i) % M;
        }
        inv[100000] = pow(f[100000], M - 2);
        for (int i = 100000 - 1; i >= 0; i--) {
            inv[i] = (inv[i + 1] * (i + 1)) % M;
        }
    }
 
    static long pow(long a, long n) {
        long res = 1;
        while (n > 0) {
            if (n % 2 == 1) {
                res = (res * a) % M;
            }
            a = (a * a) % M;
            n >>= 1;
        }
        return res;
    }
 
    static long nCr(int n, int r) {
        return (((f[n] * inv[n - r]) % M) * inv[r]) % M;
    }
 
    public static void main(String[] args) {
        int N = 2, A = 1, B = 2, C = 3, D = 5;
        System.out.println(bestNumbers(N, A, B, C, D));
    }
}
 
// This code is contributed by uttamdp_10


Python3




import math
 
done = 0
f, inv = [], []
 
class Solution:
    M = 10**9 + 7
 
    def bestNumbers(self, N, A, B, C, D):
        global done, f, inv
        if not done:
            self.pre()
        if A == B:
            s = N * A
            flag = False
            while s > 0:
                if s % 10 == C or s % 10 == D:
                    flag = True
                    break
                s //= 10
            if flag:
                return 1
            return 0
        ans = 0
        for i in range(N + 1):
            s = i * A + (N - i) * B
            flag = False
            while s > 0:
                if s % 10 == C or s % 10 == D:
                    flag = True
                    break
                s //= 10
            if flag:
                ans = (ans + self.nCr(N, i)) % self.M
        return ans
 
    def pre(self):
        global done, f, inv
        done = 1
        f = [1] * (10**5 + 1)
        inv = [0] * (10**5 + 1)
        for i in range(2, 10**5 + 1):
            f[i] = (f[i - 1] * i) % self.M
        inv[10**5] = pow(f[10**5], self.M - 2, self.M)
        for i in range(10**5 - 1, -1, -1):
            inv[i] = (inv[i + 1] * (i + 1)) % self.M
 
    def nCr(self, n, r):
        return (((f[n] * inv[n - r]) % self.M) * inv[r]) % self.M
 
# Driver's code
if __name__ == '__main__':
    obj = Solution()
    N, A, B, C, D = 2, 1, 2, 3, 5
    print(obj.bestNumbers(N, A, B, C, D))


C#




// C# Implementation:
using System;
 
public class GFG {
    private const long M = 1000000007;
 
    private static long[] f;
    private static long[] inv;
 
    // function to get the best numbers
    public static int BestNumbers(int N, int A, int B,
                                  int C, int D)
    {
        if (A == B) {
            long sum = (long)N * A;
            bool flag = false;
            while (sum > 0) {
                if ((sum % 10) == C || (sum % 10) == D) {
                    flag = true;
                    break;
                }
                sum /= 10;
            }
            if (flag)
                return 1;
            return 0;
        }
        long ans = 0;
        for (long i = 0; i <= N; i++) {
            long sum = i * A + (N - i) * B;
            bool flag = false;
            while (sum > 0) {
                if ((sum % 10) == C || (sum % 10) == D) {
                    flag = true;
                    break;
                }
                sum /= 10;
            }
            if (flag)
                ans = (ans + nCr(N, (int)i)) % M;
        }
        return (int)ans;
    }
 
    static GFG()
    {
        f = new long[100001];
        inv = new long[100001];
        f[0] = 1;
        for (int i = 1; i <= 100000; i++) {
            f[i] = (f[i - 1] * i) % M;
        }
        inv[100000] = Pow(f[100000], M - 2);
        for (int i = 100000 - 1; i >= 0; i--) {
            inv[i] = (inv[i + 1] * (i + 1)) % M;
        }
    }
 
    static long Pow(long a, long n)
    {
        long res = 1;
        while (n > 0) {
            if (n % 2 == 1) {
                res = (res * a) % M;
            }
            a = (a * a) % M;
            n >>= 1;
        }
        return res;
    }
 
    static long nCr(int n, int r)
    {
        return (((f[n] * inv[n - r]) % M) * inv[r]) % M;
    }
 
    // driver code
    public static void Main(string[] args)
    {
        int N = 2, A = 1, B = 2, C = 3, D = 5;
 
        // function call
        Console.WriteLine(BestNumbers(N, A, B, C, D));
    }
}
// This code is contributed by Tapesh(tapeshdua420)


Javascript




// Javascript code Implementation :
 
const M = 1000000007;
let f = new Array(100001);
let inv = new Array(100001);
 
function bestNumbers(N, A, B, C, D) {
    if (A === B) {
        let sum = BigInt(N) * BigInt(A);
        let flag = false;
        while (sum > 0) {
            if (sum % 10n === BigInt(C) || sum % 10n === BigInt(D)) {
                flag = true;
                break;
            }
            sum /= 10n;
        }
        if (flag) return 1;
        return 0;
    }
 
    let ans = 0n;
    for (let i = 0n; i <= BigInt(N); i++) {
        let sum = i * BigInt(A) + (BigInt(N) - i) * BigInt(B);
        let flag = false;
        while (sum > 0) {
            if (sum % 10n === BigInt(C) || sum % 10n === BigInt(D)) {
                flag = true;
                break;
            }
            sum /= 10n;
        }
        if (flag) ans = (ans + nCr(N, Number(i))) % BigInt(M);
    }
    return Number(ans);
}
 
function pre() {
    f[0] = 1n;
    for (let i = 1; i <= 100000; i++) {
        f[i] = (f[i - 1] * BigInt(i)) % BigInt(M);
    }
    inv[100000] = pow(f[100000], BigInt(M) - 2n);
    for (let i = 100000 - 1; i >= 0; i--) {
        inv[i] = (inv[i + 1] * BigInt(i + 1)) % BigInt(M);
    }
}
 
function pow(a, n) {
    let res = 1n;
    while (n > 0n) {
        if (n % 2n === 1n) {
            res = (res * a) % BigInt(M);
        }
        a = (a * a) % BigInt(M);
        n >>= 1n;
    }
    return res;
}
 
function nCr(n, r) {
    return (((f[n] * inv[n - r]) % BigInt(M)) * inv[r]) % BigInt(M);
}
 
// Initialization
pre();
 
// Testing the function
const N = 2;
const A = 1;
const B = 2;
const C = 3;
const D = 5;
console.log(bestNumbers(N, A, B, C, D));


Output

2





Time Complexity: O(N*log(N))
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads