Count integers with specific Digit Sum property
Last Updated :
04 Oct, 2023
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++
#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;
}
};
int main()
{
Solution obj;
int N = 2, A = 1, B = 2, C = 3, D = 5;
cout << obj.bestNumbers(N, A, B, C, D);
return 0;
}
|
Java
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));
}
}
|
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
if __name__ = = '__main__' :
obj = Solution()
N, A, B, C, D = 2 , 1 , 2 , 3 , 5
print (obj.bestNumbers(N, A, B, C, D))
|
C#
using System;
public class GFG {
private const 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;
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;
}
public static void Main( string [] args)
{
int N = 2, A = 1, B = 2, C = 3, D = 5;
Console.WriteLine(BestNumbers(N, A, B, C, D));
}
}
|
Javascript
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);
}
pre();
const N = 2;
const A = 1;
const B = 2;
const C = 3;
const D = 5;
console.log(bestNumbers(N, A, B, C, D));
|
Time Complexity: O(N*log(N))
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...