Given three positive integers L, R and K, the task is to count the numbers in the range [L, R] whose product of digits is equal to K
Examples:
Input: L = 1, R = 130, K = 14
Output: 3
Explanation:
Numbers in the range [1, 100] whose sum of digits is K(= 14) are:
27 => 2 * 7 = 14
72 => 7 * 2 = 14
127 => 1 * 2 * 7 = 14
Therefore, the required output is 3.Input: L = 20, R = 10000, K = 14
Output: 20
Naive Approach: The simplest approach to solve this problem is to iterate over all the numbers in the range [L, R] and for every number, check if its product of digits is equal to K or not. If found to be true, then increment the count. Finally, print the count obtained.
Below is the implementation of the above approach:
C++
// C++ program to implement // the above approach #include <bits/stdc++.h> using namespace std; // Function to find the product // of digits of a number int prodOfDigit( int N) { // Stores product of // digits of N int res = 1; while (N) { // Update res res = res * (N % 10); // Update N N /= 10; } return res; } // Function to count numbers in the range // [0, X] whose product of digit is K int cntNumRange( int L, int R, int K) { // Stores count of numbers in the range // [L, R] whose product of digit is K int cnt = 0; // Iterate over the range [L, R] for ( int i = L; i <= R; i++) { // If product of digits of // i equal to K if (prodOfDigit(i) == K) { // Update cnt cnt++; } } return cnt; } // Driver Code int main() { int L = 20, R = 10000, K = 14; cout << cntNumRange(L, R, K); } |
Java
// Java program to implement // the above approach import java.util.*; class GFG{ // Function to find the product // of digits of a number static int prodOfDigit( int N) { // Stores product of // digits of N int res = 1 ; while (N > 0 ) { // Update res res = res * (N % 10 ); // Update N N /= 10 ; } return res; } // Function to count numbers in the range // [0, X] whose product of digit is K static int cntNumRange( int L, int R, int K) { // Stores count of numbers in the range // [L, R] whose product of digit is K int cnt = 0 ; // Iterate over the range [L, R] for ( int i = L; i <= R; i++) { // If product of digits of // i equal to K if (prodOfDigit(i) == K) { // Update cnt cnt++; } } return cnt; } // Driver Code public static void main(String[] args) { int L = 20 , R = 10000 , K = 14 ; System.out.print(cntNumRange(L, R, K)); } } // This code is contributed by Amit Katiyar |
Python3
# Python3 program to implement # the above approach # Function to find the product # of digits of a number def prodOfDigit(N): # Stores product of # digits of N res = 1 while (N): # Update res res = res * (N % 10 ) # Update N N / / = 10 return res # Function to count numbers in the range # [0, X] whose product of digit is K def cntNumRange(L, R, K): # Stores count of numbers in the range # [L, R] whose product of digit is K cnt = 0 # Iterate over the range [L, R] for i in range (L, R + 1 ): # If product of digits of # i equal to K if (prodOfDigit(i) = = K): # Update cnt cnt + = 1 return cnt # Driver Code if __name__ = = '__main__' : L, R, K = 20 , 10000 , 14 print (cntNumRange(L, R, K)) # This code is contributed by mohit kumar 29 |
C#
// C# program to implement // the above approach using System; class GFG{ // Function to find the product // of digits of a number static int prodOfDigit( int N) { // Stores product of // digits of N int res = 1; while (N > 0) { // Update res res = res * (N % 10); // Update N N /= 10; } return res; } // Function to count numbers in the range // [0, X] whose product of digit is K static int cntNumRange( int L, int R, int K) { // Stores count of numbers in the range // [L, R] whose product of digit is K int cnt = 0; // Iterate over the range [L, R] for ( int i = L; i <= R; i++) { // If product of digits of // i equal to K if (prodOfDigit(i) == K) { // Update cnt cnt++; } } return cnt; } // Driver Code static void Main() { int L = 20, R = 10000, K = 14; Console.WriteLine(cntNumRange(L, R, K)); } } // This code is contributed by code_hunt |
20
Time Complexity: O(R – L + 1) * log10(R)
Auxiliary Space: O(1)
Efficient approach: To optimize the above approach, the idea is to use Digit DP. Following are the dynamic programming states of the Digit DP:
Dynamic programming states are:
prod: Represents sum of digits.
tight: Check if sum of digits exceed K or not.
end: Stores the maximum possible value of ith digit of a number.
st: Check if a number contains leading 0 or not.
Following are the Recurrence Relation of the Dynamic programming states:
- If i == 0 and st == 0:
cntNum(N, K, st, tight): Returns the count of numbers in the range [0, X] whose product of digits is K.
- Otherwise,
cntNum(N, K, st, tight): Returns the count of numbers in the range [0, X] whose product of digits is K.
Follow the steps below to solve the problem:
- Initialize a 3D array dp[N][K][tight] to compute and store the values of all subproblems of the above recurrence relation.
- Finally, return the value of dp[N][sum][tight].
Below is the implementation of the above approach:
C++
// C++ program to implement // the above approach #include <bits/stdc++.h> using namespace std; #define M 100 // Function to count numbers in the range // [0, X] whose product of digit is K int cntNum(string X, int i, int prod, int K, int st, int tight, int dp[M][M][2][2]) { // If count of digits in a number // greater than count of digits in X if (i >= X.length() || prod > K) { // If product of digits of a // number equal to K return prod == K; } // If overlapping subproblems // already occurred if (dp[prod][i][tight][st] != -1) { return dp[prod][i][tight][st]; } // Stores count of numbers whose // product of digits is K int res = 0; // Check if the numbers // exceeds K or not int end = tight ? X[i] - '0' : 9; // Iterate over all possible // value of i-th digits for ( int j = 0; j <= end; j++) { // if number contains leading 0 if (j == 0 && !st) { // Update res res += cntNum(X, i + 1, prod, K, false , (tight & (j == end)), dp); } else { // Update res res += cntNum(X, i + 1, prod * j, K, true , (tight & (j == end)), dp); } // Update res } // Return res return dp[prod][i][tight][st] = res; } // Utility function to count the numbers in // the range [L, R] whose prod of digits is K int UtilCntNumRange( int L, int R, int K) { // Stores numbers in the form // of string string str = to_string(R); // Stores overlapping subproblems int dp[M][M][2][2]; // Initialize dp[][][] to -1 memset (dp, -1, sizeof (dp)); // Stores count of numbers in // the range [0, R] whose // product of digits is k int cntR = cntNum(str, 0, 1, K, false , true , dp); // Update str str = to_string(L - 1); // Initialize dp[][][] to -1 memset (dp, -1, sizeof (dp)); // Stores count of numbers in // the range [0, L - 1] whose // product of digits is k int cntL = cntNum(str, 0, 1, K, false , true , dp); return (cntR - cntL); } // Driver Code int main() { int L = 20, R = 10000, K = 14; cout << UtilCntNumRange(L, R, K); } |
Java
// Java program to implement // the above approach import java.util.*; class GFG{ static final int M = 100 ; // Function to count numbers in the range // [0, X] whose product of digit is K static int cntNum(String X, int i, int prod, int K, int st, int tight, int [][][][]dp) { // If count of digits in a number // greater than count of digits in X if (i >= X.length() || prod > K) { // If product of digits of a // number equal to K return prod == K ? 1 : 0 ; } // If overlapping subproblems // already occurred if (dp[prod][i][tight][st] != - 1 ) { return dp[prod][i][tight][st]; } // Stores count of numbers whose // product of digits is K int res = 0 ; // Check if the numbers // exceeds K or not int end = tight > 0 ? X.charAt(i) - '0' : 9 ; // Iterate over all possible // value of i-th digits for ( int j = 0 ; j <= end; j++) { // If number contains leading 0 if (j == 0 && st == 0 ) { // Update res res += cntNum(X, i + 1 , prod, K, 0 , (tight & ((j == end) ? 1 : 0 )), dp); } else { // Update res res += cntNum(X, i + 1 , prod * j, K, 1 , (tight & ((j == end) ? 1 : 0 )), dp); } } // Return res return dp[prod][i][tight][st] = res; } // Utility function to count the numbers in // the range [L, R] whose prod of digits is K static int UtilCntNumRange( int L, int R, int K) { // Stores numbers in the form // of String String str = String.valueOf(R); // Stores overlapping subproblems int [][][][]dp = new int [M][M][ 2 ][ 2 ]; // Initialize dp[][][] to -1 for ( int i = 0 ; i < M; i++) { for ( int j = 0 ; j < M; j++) { for ( int k = 0 ; k < 2 ; k++) for ( int l = 0 ; l < 2 ; l++) dp[i][j][k][l] = - 1 ; } } // Stores count of numbers in // the range [0, R] whose // product of digits is k int cntR = cntNum(str, 0 , 1 , K, 0 , 1 , dp); // Update str str = String.valueOf(L - 1 ); // Initialize dp[][][] to -1 for ( int i = 0 ;i<M;i++) { for ( int j = 0 ; j < M; j++) { for ( int k = 0 ; k < 2 ; k++) for ( int l = 0 ; l < 2 ; l++) dp[i][j][k][l] = - 1 ; } } // Stores count of numbers in // the range [0, L - 1] whose // product of digits is k int cntL = cntNum(str, 0 , 1 , K, 0 , 1 , dp); return (cntR - cntL); } // Driver Code public static void main(String[] args) { int L = 20 , R = 10000 , K = 14 ; System.out.print(UtilCntNumRange(L, R, K)); } } // This code is contributed by shikhasingrajput |
Python3
# Python 3 program to implement # the above approach M = 100 # Function to count numbers in the range # [0, X] whose product of digit is K def cntNum(X, i, prod, K, st, tight, dp): end = 0 # If count of digits in a number # greater than count of digits in X if (i > = len (X) or prod > K): # If product of digits of a # number equal to K if (prod = = K): return 1 else : return 0 # If overlapping subproblems # already occurred if (dp[prod][i][tight][st] ! = - 1 ): return dp[prod][i][tight][st] # Stores count of numbers whose # product of digits is K res = 0 # Check if the numbers # exceeds K or not if (tight ! = 0 ): end = ord (X[i]) - ord ( '0' ) # Iterate over all possible # value of i-th digits for j in range (end + 1 ): # if number contains leading 0 if (j = = 0 and st = = 0 ): # Update res res + = cntNum(X, i + 1 , prod, K, False , (tight & (j = = end)), dp) else : # Update res res + = cntNum(X, i + 1 , prod * j, K, True , (tight & (j = = end)), dp) # Update res # Return res dp[prod][i][tight][st] = res return res # Utility function to count the numbers in # the range [L, R] whose prod of digits is K def UtilCntNumRange(L, R, K): global M # Stores numbers in the form # of string str1 = str (R) # Stores overlapping subproblems dp = [[[[ - 1 for i in range ( 2 )] for j in range ( 2 )] for k in range (M)] for l in range (M)] # Stores count of numbers in # the range [0, R] whose # product of digits is k cntR = cntNum(str1, 0 , 1 , K, False , True , dp) # Update str str1 = str (L - 1 ) dp = [[[[ - 1 for i in range ( 2 )] for j in range ( 2 )] for k in range (M)] for l in range (M)] # Stores count of numbers in cntR = 20 # the range [0, L - 1] whose # product of digits is k cntL = cntNum(str1, 0 , 1 , K, False , True , dp) return (cntR - cntL) # Driver Code if __name__ = = '__main__' : L = 20 R = 10000 K = 14 print (UtilCntNumRange(L, R, K)) # This code is contributed by SURENDRA_GANGWAR. |
C#
// C# program to implement // the above approach using System; class GFG { static readonly int M = 100; // Function to count numbers in the range // [0, X] whose product of digit is K static int cntNum(String X, int i, int prod, int K, int st, int tight, int [,,,]dp) { // If count of digits in a number // greater than count of digits in X if (i >= X.Length || prod > K) { // If product of digits of a // number equal to K return prod == K ? 1 : 0; } // If overlapping subproblems // already occurred if (dp[prod, i, tight, st] != -1) { return dp[prod, i, tight, st]; } // Stores count of numbers whose // product of digits is K int res = 0; // Check if the numbers // exceeds K or not int end = tight > 0 ? X[i] - '0' : 9; // Iterate over all possible // value of i-th digits for ( int j = 0; j <= end; j++) { // If number contains leading 0 if (j == 0 && st == 0) { // Update res res += cntNum(X, i + 1, prod, K, 0, (tight & ((j == end) ? 1 : 0)), dp); } else { // Update res res += cntNum(X, i + 1, prod * j, K, 1, (tight & ((j == end) ? 1 : 0)), dp); } } // Return res return dp[prod, i, tight, st] = res; } // Utility function to count the numbers in // the range [L, R] whose prod of digits is K static int UtilCntNumRange( int L, int R, int K) { // Stores numbers in the form // of String String str = String.Join( "" , R); // Stores overlapping subproblems int [,,,]dp = new int [M, M, 2, 2]; // Initialize [,]dp[] to -1 for ( int i = 0; i < M; i++) { for ( int j = 0; j < M; j++) { for ( int k = 0; k < 2; k++) for ( int l = 0; l < 2; l++) dp[i, j, k, l] = -1; } } // Stores count of numbers in // the range [0, R] whose // product of digits is k int cntR = cntNum(str, 0, 1, K, 0, 1, dp); // Update str str = String.Join( "" , L - 1); // Initialize [,]dp[] to -1 for ( int i = 0; i < M; i++) { for ( int j = 0; j < M; j++) { for ( int k = 0; k < 2; k++) for ( int l = 0; l < 2; l++) dp[i, j, k, l] = -1; } } // Stores count of numbers in // the range [0, L - 1] whose // product of digits is k int cntL = cntNum(str, 0, 1, K, 0, 1, dp); return (cntR - cntL); } // Driver Code public static void Main(String[] args) { int L = 20, R = 10000, K = 14; Console.Write(UtilCntNumRange(L, R, K)); } } // This code is contributed by 29AjayKumar |
20
Time Complexity: O(K * log10(R) * 10 * 4)
Auxiliary Space: O(K * log10(R) * 4)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.