Queries to count numbers from a range which does not contain digit K in their decimal or octal representation
Last Updated :
31 May, 2021
Given an integer K and an array Q[][] consisting of N queries of type {L, R}, the task for each query is to print the count of numbers from the range [L, R] that doesn’t contain the digit K in their decimal representation or octal representation.
Examples:
Input: K = 7, Q[][] = {{1, 15}}
Output: 13
Explanation:
Only number 7 and 15 contains digit K in its octal or decimal representations.
Octal representation of number 7 is 7.
Octal representation of number 15 is 17.
Input: K = 8, Q[][] = {{1, 10}}
Output: 9
Explanation:
Only number 8 contains digit K in its decimal representations.
Octal representation of number 8 is 10.
Naive Approach: The idea is to traverse the range [L, R] for each query and find those numbers whose decimal and octal representations does not contain the digit K. Print the count of such numbers.
Time Complexity: O(N2*(log10(N) + log8(N)))
Auxiliary Space: O(N)
Efficient Approach: To optimize the above approach, the idea is to pre-compute the count of all such numbers using Prefix Sum technique. Follow the steps below to solve the problem:
- Initialize an array, say pref[], to store the count of numbers in the range [0, i] that contains digit K in their octal or decimal representation.
- Now traverse the range [0, 1e6] and perform the following steps:
- If the number contains digit K in either octal representation or decimal representation, then update pref[i] as pref[i – 1] + 1.
- Otherwise, update pref[i] as pref[i – 1].
- Traverse the given queries and print the count for each query as
Q[i][1] – Q[i][0] + 1 – (pref[Q[i][1]] – pref[Q[i][0] – 1])
Below is the implementation for the above approach :
C++
#include <bits/stdc++.h>
using namespace std;
bool contains( int num, int K, int base)
{
bool isThere = 0;
while (num) {
int remainder = num % base;
if (remainder == K) {
isThere = 1;
}
num /= base;
}
return isThere;
}
void count( int n, int k,
vector<vector< int > > v)
{
int pref[1000005] = { 0 };
for ( int i = 1; i < 1e6 + 5; i++) {
bool present
= contains(i, k, 10)
|| contains(i, k, 8);
pref[i] += pref[i - 1] + present;
}
for ( int i = 0; i < n; ++i) {
cout << v[i][1] - v[i][0] + 1
- (pref[v[i][1]]
- pref[v[i][0] - 1])
<< ' ' ;
}
}
int main()
{
int K = 7;
vector<vector< int > > Q = { { 2, 5 },
{ 1, 15 } };
int N = Q.size();
count(N, K, Q);
}
|
Java
import java.util.*;
public class GFG
{
static boolean contains( int num, int K, int Base)
{
boolean isThere = false ;
while (num > 0 )
{
int remainder = num % Base;
if (remainder == K)
{
isThere = true ;
}
num /= Base;
}
return isThere;
}
static void count( int n, int k,
Vector<Vector<Integer> > v)
{
int [] pref = new int [ 1000005 ];
for ( int i = 1 ; i < 1e6 + 5 ; i++) {
boolean present
= contains(i, k, 10 )
|| contains(i, k, 8 );
if (present)
{
pref[i] += pref[i - 1 ] + 1 ;
}
}
System.out.print((v.get( 0 ).get( 1 ) - v.get( 0 ).get( 0 ) +
1 - (pref[v.get( 0 ).get( 1 )] -
pref[v.get( 0 ).get( 0 ) - 1 ])) + " " );
System.out.print((v.get( 1 ).get( 1 ) - v.get( 1 ).get( 0 ) -
(pref[v.get( 1 ).get( 1 )] -
pref[v.get( 1 ).get( 0 ) - 1 ])) + " " );
}
public static void main(String[] args)
{
int K = 7 ;
Vector<Vector<Integer> > Q = new Vector<Vector<Integer> >();
Q.add( new Vector<Integer>());
Q.get( 0 ).add( 2 );
Q.get( 0 ).add( 5 );
Q.add( new Vector<Integer>());
Q.get( 1 ).add( 1 );
Q.get( 1 ).add( 15 );
int N = Q.size();
count(N, K, Q);
}
}
|
Python3
def contains(num, K, base):
isThere = 0
while (num):
remainder = num % base
if (remainder = = K):
isThere = 1
num / / = base
return isThere
def count(n, k, v):
pref = [ 0 ] * 1000005
for i in range ( 1 , 10 * * 6 + 5 ):
present = contains(i, k, 10 ) or contains(i, k, 8 )
pref[i] + = pref[i - 1 ] + present
for i in range (n):
print (v[i][ 1 ] - v[i][ 0 ] + 1 - (pref[v[i][ 1 ]] - pref[v[i][ 0 ] - 1 ]),end = " " )
if __name__ = = '__main__' :
K = 7
Q = [ [ 2 , 5 ],
[ 1 , 15 ] ]
N = len (Q)
count(N, K, Q)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static bool contains( int num, int K, int Base)
{
bool isThere = false ;
while (num > 0)
{
int remainder = num % Base;
if (remainder == K)
{
isThere = true ;
}
num /= Base;
}
return isThere;
}
static void count( int n, int k,
List<List< int > > v)
{
int [] pref = new int [1000005];
for ( int i = 1; i < 1e6 + 5; i++) {
bool present
= contains(i, k, 10)
|| contains(i, k, 8);
if (present)
{
pref[i] += pref[i - 1] + 1;
}
}
Console.Write((v[0][1] - v[0][0] + 1 - (pref[v[0][1]] - pref[v[0][0] - 1])) + " " );
Console.Write((v[1][1] - v[1][0] - (pref[v[1][1]] - pref[v[1][0] - 1])) + " " );
}
static void Main()
{
int K = 7;
List<List< int > > Q = new List<List< int >>();
Q.Add( new List< int >());
Q[0].Add(2);
Q[0].Add(5);
Q.Add( new List< int >());
Q[1].Add(1);
Q[1].Add(15);
int N = Q.Count;
count(N, K, Q);
}
}
|
Javascript
<script>
function contains(num, K, base)
{
var isThere = 0;
while (num) {
var remainder = num % base;
if (remainder == K) {
isThere = 1;
}
num /= base;
}
return isThere;
}
function count(n, k, v)
{
var pref = Array(100005).fill(0);
for ( var i = 1; i < 100005; i++) {
var present
= contains(i, k, 10)
|| contains(i, k, 8);
pref[i] += pref[i - 1] + present;
}
for ( var i = 0; i < n; ++i) {
document.write( v[i][1] - v[i][0] + 1
- (pref[v[i][1]]
- pref[v[i][0] - 1])
+ ' ');
}
}
var K = 7;
var Q = [ [ 2, 5 ], [1, 15 ]];
var N = Q.length;
count(N, K, Q);
</script>
|
Time Complexity:O(N*(log 10(N)+log8(N)))
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...