Queries to count numbers from given range which are divisible by all its digits
Last Updated :
21 Apr, 2021
Given a 2D array arr[][] with each row of the form of a query { L, R }, the task is to count the numbers in the range [L, R] such that the number is divisible by all of its non-zero digit.
Examples:
Input: arr[][] ={ {1, 5}, {12, 14} }
Output: 5 1
Explanation:
Query1: All the numbers in the range [1, 5] are divisible by their digits.
Query2: Numbers in the range [12, 14] which are divisible by all of its digits is 12 only.
Input: arr[][] = { {1, 20} }
Output:14
Explanation:
Numbers in the range [1, 20] which are divisible by all of its non-zero digits are: { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 20}
Naive Approach: The simplest approach to solve this problem is to traverse the array arr[][] and for every ith row of the array, iterate over the range [L, R]. For every element in the range, check if the number is divisible by all of its non-zero digits or not. If found to be true, then increment the count. Finally, print the count obtained.
Time Complexity: O(N * (R – L)), where N is the count of rows
Auxiliary Space: O(1)
Efficient approach: The above approach can be optimized by finding the maximum possible value of arr[i][1] and precompute the count of numbers which is divisible by its non-zero digits using Prefix Sum technique. Follow the steps below to solve the problem:
- Initialize a variable, say Max, to store the maximum possible value of arr[i][1].
- Initialize an array, say prefCntDiv[], where prefCntDiv[i] stores the count of numbers from the range [1, i] which is divisible by its non-zero digits.
- Iterate over the range [1, Max]. For every ith iteration, check if i is divisible by all of its non-zero digits or not. If found to be true, then update prefCntDiv[i] = prefCntDiv[i – 1] + 1.
- Otherwise, update prefCntDiv[i] = prefCntDiv[i – 1].
- Traverse the array arr[]. For every ith row of the array, print prefCntDiv[arr[i][1]] – prefCntDiv[arr[i][0] – 1].
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define Max 1000005
bool CheckDivByAllDigits( int number)
{
int n = number;
while (n > 0) {
if (n % 10)
if (number % (n % 10)) {
return false ;
}
n /= 10;
}
return true ;
}
void cntNumInRang( int arr[][2], int N)
{
int prefCntDiv[Max] = { 0 };
for ( int i = 1; i <= Max; i++) {
prefCntDiv[i] = prefCntDiv[i - 1]
+ (CheckDivByAllDigits(i));
}
for ( int i = 0; i < N; i++)
cout << (prefCntDiv[arr[i][1]]
- prefCntDiv[arr[i][0] - 1])
<< " " ;
}
int main()
{
int arr[][2] = { { 1, 5 }, { 12, 14 } };
int N = sizeof (arr) / sizeof (arr[0]);
cntNumInRang(arr, N);
return 0;
}
|
Java
import java.io.*;
class GFG
{
public static int Max = 1000005 ;
static boolean CheckDivByAllDigits( int number)
{
int n = number;
while (n > 0 )
{
if (n % 10 != 0 )
if (number % (n % 10 ) != 0 )
{
return false ;
}
n /= 10 ;
}
return true ;
}
static void cntNumInRang( int arr[][], int N)
{
int prefCntDiv[] = new int [Max + 1 ];
for ( int i = 1 ; i <= Max; i++)
{
int ans = 0 ;
if (CheckDivByAllDigits(i))
ans = 1 ;
prefCntDiv[i] = prefCntDiv[i - 1 ] + ans;
}
for ( int i = 0 ; i < N; i++)
System.out.print((prefCntDiv[arr[i][ 1 ]]
- prefCntDiv[arr[i][ 0 ] - 1 ])
+ " " );
}
public static void main(String[] args)
{
int arr[][] = { { 1 , 5 }, { 12 , 14 } };
int N = arr.length;
cntNumInRang(arr, N);
}
}
|
Python3
def CheckDivByAllDigits(number):
n = number
while (n > 0 ):
if (n % 10 ):
if (number % (n % 10 )):
return False
n / / = 10
return True
def cntNumInRang(arr, N):
global Max
prefCntDiv = [ 0 ] * Max
for i in range ( 1 , Max ):
prefCntDiv[i] = prefCntDiv[i - 1 ] + (CheckDivByAllDigits(i))
for i in range (N):
print (prefCntDiv[arr[i][ 1 ]] - prefCntDiv[arr[i][ 0 ] - 1 ], end = " " )
if __name__ = = '__main__' :
arr = [ [ 1 , 5 ], [ 12 , 14 ]]
Max = 1000005
N = len (arr)
cntNumInRang(arr, N)
|
C#
using System;
class GFG
{
public static int Max = 1000005;
static bool CheckDivByAllDigits( int number)
{
int n = number;
while (n > 0) {
if (n % 10 != 0)
if (number % (n % 10) != 0)
{
return false ;
}
n /= 10;
}
return true ;
}
static void cntNumInRang( int [, ] arr, int N)
{
int [] prefCntDiv = new int [Max + 1];
for ( int i = 1; i <= Max; i++) {
int ans = 0;
if (CheckDivByAllDigits(i))
ans = 1;
prefCntDiv[i] = prefCntDiv[i - 1] + ans;
}
for ( int i = 0; i < N; i++)
Console.Write((prefCntDiv[arr[i, 1]]
- prefCntDiv[arr[i, 0] - 1])
+ " " );
}
public static void Main( string [] args)
{
int [, ] arr = { { 1, 5 }, { 12, 14 } };
int N = arr.GetLength(0);
cntNumInRang(arr, N);
}
}
|
Javascript
<script>
const Max = 1000005;
function CheckDivByAllDigits(number)
{
let n = number;
while (n > 0) {
if (n % 10)
if (number % (n % 10)) {
return false ;
}
n = parseInt(n / 10);
}
return true ;
}
function cntNumInRang(arr, N)
{
let prefCntDiv = new Array(Max).fill(0);
for (let i = 1; i <= Max; i++) {
prefCntDiv[i] = prefCntDiv[i - 1]
+ (CheckDivByAllDigits(i));
}
for (let i = 0; i < N; i++)
document.write((prefCntDiv[arr[i][1]]
- prefCntDiv[arr[i][0] - 1])
+ " " );
}
let arr = [ [ 1, 5 ], [ 12, 14 ] ];
let N = arr.length;
cntNumInRang(arr, N);
</script>
|
Time Complexity: O(N + Max), where Max is the maximum value of arr[i][1]
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...