Given a range [L, R], the task is to count the numbers which have even number of odd digits and odd number of even digits. For example,
- 8 has 1 even digit and 0 odd digit – Satisfies the condition since 1 is odd and 0 is even.
- 545 has 1 even digit and 2 odd digits – Satisfies the condition since 1 is odd and 2 is even.
- 4834 has 3 even digits and 1 odd digit – Does not satisfy the condition since there are odd numbers(i.e 1) of odd digits.
Examples:
Input: L = 1, R = 9
Output: 4
2, 4, 6 and 8 are the only integers from the
given range that satisfy the given conditions.Input: L = 1, R = 19
Output: 4Input: L = 123, R = 984
Output: 431
Approach:
-
Case 1
There is a pattern in which these numbers occur betweenand (where 1<=k<=18).
Number of occurrences from- 1 – 10 and 1 – 100 are 4
- 1 – 1000 and 1 – 10000 are 454
- 1 – 10000 and 1 – 100000 are 45454
-
Case 2
- If the number of digits in a number is even then it cannot satisfy the given condition because we need an odd number(of digits) and an even number(of digits) to satisfy our condition and odd number + even number is always odd
- So if the number of digits for a given number(say n) is even then its number of occurrences from 1 is equal to the number of occurrences from
to largest (1<=k<=18) which is less than n
Example:
Let n = 19, number of digits in 19 are 2
Therefore number of occurrences from 1 – 19 = number of occurrences from 1 – 10 (since 10 the largestless than 19)
-
Case 3
If number of digits for a given number(say n) are odd then number of occurrences betweenand n is equal to
where
Implementation: Now we now how to calculate the number of occurrences from 1 to given n. Therefore,
Number of occurrences from L to R = NumberOfOccurrencesUpto(R) – NumberOfOccurrencesUpto(L – 1) where L is not equal to 1.
Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
#define ll long long // Pattern table from Case 1 map<ll, ll> values{{1, 0}, {10, 4},
{100, 4},
{1000, 454},
{10000, 454},
{100000, 45454},
{1000000, 45454},
{10000000, 4545454},
{100000000, 4545454},
{1000000000, 454545454},
{10000000000, 454545454},
{100000000000, 45454545454},
{1000000000000, 45454545454},
{10000000000000, 4545454545454},
{100000000000000, 4545454545454},
{1000000000000000, 454545454545454},
{10000000000000000, 454545454545454},
{100000000000000000, 45454545454545454},
{1000000000000000000, 45454545454545454}};
// Function that returns the number of // even and odd digits in val pair<ll, ll> count_even_odd(ll val) { ll even = 0, odd = 0;
while (val)
{
ll num = val % 10;
if (num % 2 == 0)
even++;
else
odd++;
val /= 10;
}
return make_pair(even, odd);
} // Function that returns True if num // satisfies the given condition bool satisfies_condition(ll num)
{ pair<ll, ll> answer = count_even_odd(num);
ll even = answer.first;
ll odd = answer.second;
if (even % 2 == 1 and
odd % 2 == 0) return true ;
return false ;
} // Function to return the count of // numbers from 1 to val that // satisfies the given condition ll count_upto(ll val) { // If the value is already present
// in the values dict
if (values.find(val) != values.end())
return values[val];
ll index = 1;
for ( int i = 0;
i < to_string(val).length() - 1;
i++)
index *= 10;
// If the value is even
// Case 2
if (to_string(val).length() % 2 == 0)
return values[index];
ll val_len = to_string(val).length();
ll cnt = values[index];
// Now the problem is to count the desired
// numbers from 10**(val_len-1) + 1 to val
ll left_end = index + 1;
// Case 3
// Eliminating all the even numbers
cnt += (val - left_end) / 2;
if (satisfies_condition(val) or
satisfies_condition(left_end))
cnt++;
return cnt;
} // Driver Code int main()
{ // Input l and r
ll l = 123, r = 984;
ll right = count_upto(r);
ll left = 0;
if (l == '1' )
left = 0;
else
left = count_upto(l - 1);
cout << right - left << endl;
return 0;
} // This code is contributed by // sanjeev2552 |
// Java implementation of the approach import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
// Pattern table from Case 1 static HashMap<Long, Long> values = new HashMap<>();
public static void intitializeMap()
{ values = new HashMap<>();
values.put(1L, 0L);
values.put(10L, 4L);
values.put(100L, 4L);
values.put(1000L, 454L);
values.put(10000L, 454L);
values.put(100000L, 45454L);
values.put(1000000L, 45454L);
values.put(10000000L, 4545454L);
values.put(100000000L, 4545454L);
values.put(1000000000L, 454545454L);
values.put(10000000000L, 454545454L);
values.put(100000000000L, 45454545454L);
values.put(1000000000000L, 45454545454L);
values.put(10000000000000L, 4545454545454L);
values.put(100000000000000L, 4545454545454L);
values.put(1000000000000000L, 454545454545454L);
values.put(10000000000000000L, 454545454545454L);
values.put(100000000000000000L, 45454545454545454L);
values.put(1000000000000000000L, 45454545454545454L);
} // Function that returns the number of // even and odd digits in val static long [] count_even_odd( long val)
{ long even = 0 , odd = 0 ;
while (val > 0 )
{
long num = val % 10 ;
if (num % 2 == 0 )
even++;
else
odd++;
val /= 10 ;
}
return ( new long [] { even, odd });
} // Function that returns True if num // satisfies the given condition static boolean satisfies_condition( long num)
{ long [] answer = count_even_odd(num);
long even = answer[ 0 ];
long odd = answer[ 1 ];
if (even % 2 == 1 && odd % 2 == 0 )
return true ;
return false ;
} // Function to return the count of // numbers from 1 to val that // satisfies the given condition static long count_upto( long val)
{ // If the value is already present
// in the values dict
if (values.containsKey(val))
return values.get(val);
long index = 1 ;
for ( int i = 0 ;
i < Long.toString(val).length() - 1 ;
i++)
index *= 10 ;
// If the value is even
// Case 2
if (Long.toString(val).length() % 2 == 0 )
return values.get(index);
long val_len = Long.toString(val).length();
long cnt = values.get(index);
// Now the problem is to count the desired
// numbers from 10**(val_len-1) + 1 to val
long left_end = index + 1 ;
// Case 3
// Eliminating all the even numbers
cnt += (val - left_end) / 2 ;
if (satisfies_condition(val) ||
satisfies_condition(left_end))
cnt++;
return cnt;
} // Driver Code public static void main(String[] args)
{ // Input l and r
long l = 123 , r = 984 ;
// Function to initialize the Map
intitializeMap();
long right = count_upto(r);
long left = 0 ;
if (l == '1' )
left = 0 ;
else
left = count_upto(l - 1 );
System.out.println(right - left);
} } // This code is contributed by Kingash |
# Python3 implementation of the approach # Pattern table from Case 1 values = {
1 : 0 ,
10 : 4 ,
100 : 4 ,
1000 : 454 ,
10000 : 454 ,
100000 : 45454 ,
1000000 : 45454 ,
10000000 : 4545454 ,
100000000 : 4545454 ,
1000000000 : 454545454 ,
10000000000 : 454545454 ,
100000000000 : 45454545454 ,
1000000000000 : 45454545454 ,
10000000000000 : 4545454545454 ,
100000000000000 : 4545454545454 ,
1000000000000000 : 454545454545454 ,
10000000000000000 : 454545454545454 ,
100000000000000000 : 45454545454545454 ,
1000000000000000000 : 45454545454545454 ,
} # Function that returns the number of # even and odd digits in val def count_even_odd(val):
even = odd = 0
while val > 0 :
num = val % 10
if num % 2 = = 0 :
even + = 1
else :
odd + = 1
val / / = 10
return even, odd
# Function that returns True if num # satisfies the given condition def satisfies_condition(num):
even, odd = count_even_odd(num)
if even % 2 = = 1 and odd % 2 = = 0 :
return True
return False
# Function to return the count of numbers # from 1 to val that satisfies the given condition def count_upto(val):
# If the value is already present in the
# values dict
if int (val) in values:
return values[ int (val)]
# If the value is even
# Case 2
if len (val) % 2 = = 0 :
return values[ int ( '1' + '0' * ( len (val) - 1 ))]
val_len = len (val)
count = values[ int ( '1' + '0' * (val_len - 1 ))]
# Now the problem is to count the desired
# numbers from 10**(val_len-1) + 1 to val
left_end = int ( '1' + '0' * (val_len - 1 )) + 1
# Case 3
# Eliminating all the even numbers
count + = ( int (val) - left_end) / / 2
if satisfies_condition( int (val)) or satisfies_condition(left_end):
count + = 1
return count
if __name__ = = '__main__' :
# Input L and R ( as a string )
l, r = '123' , '984'
right = count_upto(r)
left = 0
if (l = = '1' ):
left = 0
else :
left = count_upto( str ( int (l) - 1 ))
print (right - left)
|
// C# implementation of the approach using System;
using System.Collections.Generic;
class GFG{
// Pattern table from Case 1 static Dictionary< long ,
long > values = new Dictionary< long ,
long >();
public static void intitializeMap()
{ values = new Dictionary< long , long >();
values.Add(1L, 0L);
values.Add(10L, 4L);
values.Add(100L, 4L);
values.Add(1000L, 454L);
values.Add(10000L, 454L);
values.Add(100000L, 45454L);
values.Add(1000000L, 45454L);
values.Add(10000000L, 4545454L);
values.Add(100000000L, 4545454L);
values.Add(1000000000L, 454545454L);
values.Add(10000000000L, 454545454L);
values.Add(100000000000L, 45454545454L);
values.Add(1000000000000L, 45454545454L);
values.Add(10000000000000L, 4545454545454L);
values.Add(100000000000000L, 4545454545454L);
values.Add(1000000000000000L, 454545454545454L);
values.Add(10000000000000000L, 454545454545454L);
values.Add(100000000000000000L, 45454545454545454L);
values.Add(1000000000000000000L, 45454545454545454L);
} // Function that returns the number of // even and odd digits in val static long [] count_even_odd( long val)
{ long even = 0, odd = 0;
while (val > 0)
{
long num = val % 10;
if (num % 2 == 0)
even++;
else
odd++;
val /= 10;
}
return ( new long []{ even, odd });
} // Function that returns True if num // satisfies the given condition static bool satisfies_condition( long num)
{ long [] answer = count_even_odd(num);
long even = answer[0];
long odd = answer[1];
if (even % 2 == 1 && odd % 2 == 0)
return true ;
return false ;
} // Function to return the count of // numbers from 1 to val that // satisfies the given condition static long count_upto( long val)
{ // If the value is already present
// in the values dict
if (values.ContainsKey(val))
return values[val];
long index = 1;
for ( int i = 0;
i < val.ToString().Length - 1;
i++)
index *= 10;
// If the value is even
// Case 2
if (val.ToString().Length % 2 == 0)
return values[index];
long val_len = val.ToString().Length;
long cnt = values[index];
// Now the problem is to count the desired
// numbers from 10**(val_len-1) + 1 to val
long left_end = index + 1;
// Case 3
// Eliminating all the even numbers
cnt += (val - left_end) / 2;
if (satisfies_condition(val) ||
satisfies_condition(left_end))
cnt++;
return cnt;
} // Driver Code public static void Main(String[] args)
{ // Input l and r
long l = 123, r = 984;
// Function to initialize the Map
intitializeMap();
long right = count_upto(r);
long left = 0;
if (l == '1' )
left = 0;
else
left = count_upto(l - 1);
Console.WriteLine(right - left);
} } // This code is contributed by umadevi9616 |
<script> // JavaScript implementation of the approach // Pattern table from Case 1 let values = new Map();
values.set(1, 0) values.set(10, 4) values.set(100, 4) values.set(1000, 454) values.set(10000, 454) values.set(100000, 45454) values.set(1000000, 45454) values.set(10000000, 4545454) values.set(100000000, 4545454) values.set(1000000000, 454545454) values.set(10000000000, 454545454) values.set(100000000000, 45454545454) values.set(1000000000000, 45454545454) values.set(10000000000000, 4545454545454) values.set(100000000000000, 4545454545454) values.set(1000000000000000, 454545454545454) values.set(10000000000000000, 454545454545454) values.set(100000000000000000, 45454545454545454) values.set(1000000000000000000, 45454545454545454) // Function that returns the number of // even and odd digits in val function count_even_odd(val)
{ let even = 0, odd = 0;
while (val)
{
let num = val % 10;
if (num % 2 == 0)
even++;
else
odd++;
val = Math.floor(val/10);
}
return [even, odd];
} // Function that returns True if num // satisfies the given condition function satisfies_condition(num)
{ let answer = count_even_odd(num);
let even = answer[0];
let odd = answer[1];
if (even % 2 == 1 &&
odd % 2 == 0) return true ;
return false ;
} // Function to return the count of // numbers from 1 to val that // satisfies the given condition function count_upto(val)
{ // If the value is already present
// in the values dict
if (values.has(val) == true )
return values.get(val);
let index = 1;
for (let i = 0;i < val.toString().length - 1;i++)
index *= 10;
// If the value is even
// Case 2
if (val.toString().length % 2 == 0)
return values.get(index);
let val_len = Number.toString(val).length;
let cnt = values.get(index);
// Now the problem is to count the desired
// numbers from 10**(val_len-1) + 1 to val
let left_end = index + 1;
// Case 3
// Eliminating all the even numbers
cnt += Math.floor((val - left_end) / 2);
if (satisfies_condition(val) ||
satisfies_condition(left_end))
cnt++;
return cnt;
} // Driver Code // Input l and r let l = 123, r = 984; let right = count_upto(r); let left = 0; if (l == '1' )
left = 0;
else left = count_upto(l - 1);
document.write(right - left); // This code is contributed by shinjanpatra </script> |
Output:
431
Time Complexity: O(logn)
Auxiliary Space: O(19*2)